Question

J'utilise Castle ActiveRecord, mais cette question s’applique également à NHibernate puisqu’une solution qui fonctionne avec NHibernate devrait fonctionner pour ActiveRecord. Quoi qu'il en soit, ce que j'ai est une structure de table sous-jacente comme celle-ci:

TableA -hasMany- > TableB

J'ai les objets correspondants EntityA et EntityB. EntityA a une liste IList d'objets EntityB. Cette partie fonctionne bien. Maintenant, je veux que EntityB ait une sorte de référence à EntityA. Je sais que je peux utiliser l'attribut BelongsTo sur EntityB pour lui donner une référence réelle au type EntityA complet, tel que:

[BelongsTo("tableAid")]
public EntityA Parent { get; set; }

Mais ce que j'aimerais vraiment faire, c'est:

[BelongsTo("tableAid")]
public int ParentId { get; set; }

Ainsi, EntityB ne stockerait que l’ID de l’objet parent, pas une référence à l’objet réel. C'est un exemple trivial, mais j'ai de bonnes raisons de vouloir suivre cette approche. Dans l'application sur laquelle je travaille, nous avons des pages qui affichent des objets spécifiques de type EntityB et nous aimerions que ces pages incluent des liens (comme des liens hypertexte) vers les pages parent correspondantes. Nous pouvons le faire en utilisant la première approche ci-dessus, mais cela nécessite que tout l'objet EntityA soit chargé alors que tout ce dont j'ai besoin, c'est de l'ID. Ce n'est pas une affaire énorme, mais cela semble juste un gaspillage. Je sais que je peux utiliser le chargement paresseux, mais encore une fois, cela me ressemble plus à un piratage ...

J'ai essayé de marquer la clé étrangère avec l'attribut [Property] comme suit:

[Property]
public int ParentId { get; set; }

Le problème de cette approche est qu'EntityB.ParentId reste null lorsque vous effectuez une EntityA.SaveAndFlush () sur une nouvelle arborescence d'objets. La valeur correcte est en cours d'écriture dans la base de données, et je peux la forcer dans EntityB.ParentId en effectuant un EntityA.Refresh (), mais là encore, cela semble être un peu un hack.

Était-ce utile?

La solution

Le chargement paresseux est exactement ce que vous voulez - et ce n’est pas non plus un hack, c’est un outil bien testé et cuit dans le cadre de NHIbernate et un outil important pour le réglage des performances d’une application NHibernate importante.

Si vous deviez marquer votre " parent " EntityA étant chargé paresseux, se référant à EntityB.Parent.Id ne chargerait pas EntityA (car en coulisse, NHIbernate a déjà chargé l'identifiant d'EntityA lors du chargement d'EntityB), vous permettant ainsi de configurer vos liens sans entraîner de pénalité en termes de performances.

Autres conseils

Seulement ceci:

[Property] public int ParentId { get; set; }

... en supposant que ParentId est le nom de colonne réel.

Quelques autres commentaires.

Tout d’abord, vous devriez envisager de toute façon le chargement paresseux de toute façon. Si vous les chargez avec impatience, vous devez être conscient des cascades de charges désireuses, qui peuvent nuire gravement aux performances. Pour ce faire, vous devez marquer tous les membres publics de la classe paresseuse comme virtuelle.

Deuxièmement, sachez que chaque fois que vous avez une association un-à-plusieurs sans relation correspondante de l’enfant au parent, vous devez rendre le FK nullable dans la base de données. En effet, lorsque NH crée de nouveaux éléments enfants, il l'insère avec l'identifiant parent null puis, dans un deuxième temps, le met à jour.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top