2009-10-03 8 views
-1

Utilisation de NHibernate 2.0, attributs de classe NHibernate pour les mappages, ASP.NET MVC pour créer une application de type tableau de messages.NHibernate - objet enfant est null

J'ai 2 entités, poste et utilisateur. La publication a une propriété propriétaire qui est une instance de l'utilisateur. Il a également une propriété Replies qui est une collection de type ISet.

L'idée est qu'un poste peut avoir un niveau de réponses, le même qu'un message SO avec des commentaires. Ma page MVC utilise une vue partielle (de type Mvc.ViewUserControl) pour afficher les messages de niveau supérieur (parent). La vue partielle ParentPost utilise à son tour une vue partielle ChildPost (également de type Mvc.ViewUserControl) pour afficher les réponses (balisage d'affichage différent pour les réponses).

Tout fonctionne très bien, sauf que les instances Propriétaire de type Utilisateur sont null dans la collection Réponses. Ils sont très bien chargés dans la collection parent. En d'autres termes, au niveau parent, toutes les propriétés sont chargées correctement, y compris le propriétaire de la publication. Dans la collection Réponses, les messages de réponse sont chargés avec toutes les propriétés sauf pour leurs propriétaires. Pour ce que ça vaut, Owner est la seule propriété de classe de Post. Est-ce que quelqu'un peut m'aider à comprendre comment faire pour que NHibernate charge les instances Owner dans la collection Replies?

Voici la cartographie pertinente pour la Poste:

[Class(Table="t_Posts",Lazy=false)] 
public class Post : IPost 
{ 
    [Id(Name = "PostId")] 
    public virtual long PostId { get; set; } 

    [Property(Column="OwnerID")] 
    public virtual long OwnerId { get; set; } 

    [Property(Column="DatePosted")] 
    public virtual DateTime DatePosted { get; set; } 

    [OneToOne(0,ForeignKey="OwnerId",Lazy=Laziness.False,ClassType=typeof(User))] 
    public virtual IUser Owner { get; set; } 

    [Property(Column="ParentID")] 
    public virtual long ParentId { get; set; } 

    [Set(0,Name="Replies",Inverse=true,Cascade="all-delete-orphan", Lazy=false)] 
    [Key(1,Column="ParentId")] 
    [OneToMany(2,ClassType=typeof(Post))] 
    public virtual ISet<Post> Replies{ get; set; } 
} 

Voici la cartographie pertinente pour l'utilisateur:

[Class(Lazy=false,Table="t_Users")] 
public class User : IUser 
{ 
    [Id(Name="UserId")] 
    public virtual long UserId { get; set; } 

    [Property(Column="LoginName")] 
    public virtual string LoginName { get; set; } 
} 

Répondre

1

Pour Post.Owner, vous devriez la carte avec un grand nombre à un. Mon exemple en XML

<many-to-one name="Owner" lazy="false" column="OwnerId"/> 

Le mappage un-à-un supposera que les deux entités ont la même valeur d'ID. Un autre point à noter est, ForeignKey dans NH Mapping signifie le nom de FK, pas de colonne de clé étrangère.

Une note amicale ici, vous n'avez pas besoin des propriétés OwnerId et Owner. Tout ce dont vous avez besoin est juste la propriété du propriétaire. Vous n'avez pas besoin propriété ParentId aussi, mais assurez-vous de définir Inverse = false sur Post.Replies

Exemple complet:

public class Post 
{ 
    public virtual long PostId { get; set; } 
    public virtual DateTime DatePosted { get; set; } 
    public virtual User Owner { get; set; } 
    public virtual ISet<Post> Replies { get; set; } 

    public Post() 
    { 
     Replies = new HashedSet<Post>(); 
    } 
} 

public class User 
{ 
    public virtual long UserId { get; set; } 
    public virtual string LoginName { get; set; } 
} 

de cartographie Post

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
        namespace="Mfs.Core" 
        assembly="Mfs.Core"> 
    <class name="Post" table="tPost" lazy="false"> 
    <id name="PostId"> 
     <generator class="hilo"></generator> 
    </id> 

    <property name="DatePosted" type="timestamp"/> 

    <!--<one-to-one name="Owner" lazy="false" foreign-key="OwnerId"/>--> 
    <many-to-one name="Owner" lazy="false" column="OwnerId"/> 

    <set name="Replies" inverse="false" cascade="all-delete-orphan" lazy="false"> 
     <key column="ParentId"/> 
     <one-to-many class="Post" /> 
    </set> 
    </class> 
</hibernate-mapping> 

de cartographie de l'utilisateur

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
        namespace="Mfs.Core" 
        assembly="Mfs.Core"> 
    <class name="User" table="tUser" lazy="false"> 
    <id name="UserId"> 
     <generator class="hilo"></generator> 
    </id> 
    <property name="LoginName"></property> 
    </class> 
</hibernate-mapping> 
+0

Ah, merci! C'était ça. Première fois avec NHibernate, ça me rendait fou. Je pense que je vais revenir en arrière et lire à nouveau les chapitres de l'association :) BTW- merci pour la note sur le OwnerID. Je sais que je n'avais pas besoin de ça, c'est juste là quand j'essayais juste de charger Post avant de descendre le chemin de l'association. Merci encore!!! – squillman

Questions connexes