NHibernate - 子对象为null

时间:2009-10-03 16:10:53

标签: asp.net-mvc nhibernate load

使用NHibernate 2.0,NHibernate类属性进行映射,ASP.NET MVC创建一个留言板类型的应用程序。

我有2个实体,帖子和用户。 Post有一个Owner属性,它是User的一个实例。它还有一个Replies属性,它是ISet类型的集合。

这个想法是,一个帖子可以有一个级别的回复,与带有评论的SO帖子相同。我的MVC页面使用部分视图(类型为Mvc.ViewUserControl)来显示顶级(父级)帖子。 ParentPost局部视图依次使用ChildPost局部视图(也是Mvc.ViewUserControl类型)来显示回复(回复的不同显示标记)。

除了在回复集合中类型为User的Owner实例为null之外,一切都很有效。它们在父集合中加载得很好。

换句话说,在父级别,所有属性都被正确加载,包括帖子的所有者。在回复集合中,回复帖子将加载除其所有者之外的所有属性。对于它的价值,所有者是Post的唯一类属性。

有人可以帮我弄清楚如何让NHibernate加载回复集合中的所有者实例吗?

以下是Post的相关映射:

[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; }
}

以下是User的相关映射:

[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; }
}

1 个答案:

答案 0 :(得分:1)

对于Post.Owner,您应该将其映射为多对一。我在XML中的例子

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

一对一映射将假设两个实体具有相同的ID值。 还有一点需要注意的是,NH Mapping中的ForeignKey表示FK的名称,而不是外键列。

这里有一个友好的说明,你不需要OwnerId和Owner属性。您所需要的只是所有者财产。您也不需要ParentId属性,但请确保在Post.Replies上设置Inverse = false

完整示例:

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; }
}

帖子的映射

<?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>

用户的映射

<?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>