J'ai deux objets métier associés - A et B. L'association est (A-> B) plusieurs-à-une, avec une clé étrangère dans un (A A.B_ID dans la DB). P>
J'utilise paresseux = vrai et résolu la plupart de mes problèmes, Toutefois, dans la touche de Tostring, je veux imprimer aussi A.B.ID, que je devrais avoir sans plus de voyages à la DB. Mais accéder à A.B active le proxy et, étant donné que cela n'est pas dans le contexte d'une session ouverte, jette une exception. P>
Une solution facile mais laide serait d'avoir une propriété a.b_id. Mais cela fait partie des choses que nous essayions d'éviter en premier lieu. toute façon "biologique" de faire cela? :) merci! p>
Mise à jour: il suffit de lire sur la mise en cache et la session.get.get vs session.load. Avant que je ne soit que nouveau que l'on jette une exception si l'objet n'existe pas (Session.load), et l'autre renvoie un objet Null (Session.get). Après avoir lu sur la cachette ici A>, il est clair que Session.Load retourne un proxy à l'objet, et la seule l'extrait lazieusement lorsqu'une propriété autre que l'ID est accessible, ce qui ressemble beaucoup à ce dont j'ai besoin d'associations! Pour l'instant, j'ai ajouté les identifiants d'objet séparés (ajouté B_ID à A afin que je puisse y accéder comme A.B_ID au lieu d'utiliser A.B.IDE) P>
3 Réponses :
Pour la même raison, j'ai utilisé des propriétés explicites A.B-ID pour toutes mes relations de plusieurs personnes. Je ne vois pas cela comme une solution rapide et sale car elle fournit une solution à ce problème et que beaucoup de flexibilité est la zone de mise à jour de sauvegarde, c'est-à-dire que je n'ai pas besoin de récupérer de la base de données l'objet B juste pour l'affecter à un afin de créer l'association lorsque j'ai le B_ID dans une chaîne de requête ou quelque part ailleurs.
Mes fichiers de mappage On ressemblent à ce que ceci: p>
<property name="CreatorID" column="CreatorID" type="Int32" not-null="true" /> <many-to-one name="Creator" column="CreatorID" class="SystemUser" insert="false" update="false" cascade="none" />
Je souhaite toujours que cela puisse être fait à l'aide de Just Abid - je n'aime pas les données en double - j'avais ces propriétés et supprimé i> eux ... Je vais enquêter sur la question plus loin, mais pour l'instant c'est ce que c'est quoi Je ferai. Merci!
@Yonatankarni est entièrement d'accord. Il y a aussi une question de performance majeure avec cela. Ajoutez un grand nombre, N, d'entités «proxy» à une collection d'entités (avec un type de support défini), et elle tue les performances, car n Sélectionne, un par proxy, est effectué de manière séquentielle, en tant que set.add < / code> fait sa chose.
Si vous utilisez NHibernate 3.2 ou version ultérieure, vous pouvez utiliser le code suivant pour obtenir l'identifiant de l'objet associé sans une autre étape dans la base de données pour charger l'objet entier:
using NHibernate.Proxy; ... object id = null; if (obj.IsProxy()) // obj is the object you want to get its identifier. { var proxy = obj as INHibernateProxy; if (proxy != null) { var li = proxy.HibernateLazyInitializer; if (li != null) id = li.Identifier; } }
Vous pouvez utiliser la méthode GetIdentifier de la session NHibernate:
session.GetIdentifier(obj);
Comme je l'ai dit, juste pour l'impression de journal, etc., dans la touche Tostring (). Je n'ai pas besoin d'autres champs de B. Juste l'ID.