NHibernate中的双向一对多

时间:2011-09-20 05:44:59

标签: c# .net nhibernate nhibernate-mapping

以下是映射:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="cs_nhibernate_test1"
                   namespace="cs_nhibernate_test1">

    <class name="User" table="users">
      <id name="Id" type="int">
        <column name="Id" not-null="true" />
        <generator class="native"/>
      </id>
      <property name="Name" column="Name" />
      <property name="Age" column="Age" />      
      <bag name="Posts" inverse="true" cascade="all">
        <key column="UserId" />
        <one-to-many class="Post" />
      </bag>      
    </class>

    <class name="Post" table="posts">
      <id name="Id" type="int">
        <column name="Id" not-null="true" />
        <generator class="native"/>
      </id>
      <property name="Text" column="Text" />
      <many-to-one name="User" column="UserId" />
    </class>

</hibernate-mapping>

以下是代码:

public class User
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual int Age { get; set; }
    public virtual IList<Post> Posts { get; set; }

    public override string ToString()
    {
        return string.Format("User{{id={0}, name='{1}', age={2}}}", Id, Name, Age);
    }
}

public class Post
{
    public virtual int Id { get; set; }
    public virtual string Text { get; set; }
    public virtual User User { get; set; }

    public override string ToString()
    {
        return string.Format("Post{{id={0}, text='{1}', user={2}}}", Id, Text, User);
    }
}

    static void Main(string[] args)
    {
        ...
        ISessionFactory sessionFactory = cfg.BuildSessionFactory();
        using (ISession session = sessionFactory.OpenSession())
        {
            using (ITransaction transaction = session.BeginTransaction())
            {
                for (int i = 0; i < 3; ++i)
                {
                    var user = new User
                    {
                        Name = string.Format("John Smith #{0}", i + 1),
                        Age = 25 + i,
                        Posts = new List<Post>()
                    };

                    for (int j = 0; j < 3; ++j )
                    {
                        var post = new Post
                        {
                            Text = string.Format("qwerty {0} {1}", i, j)
                        };
                        user.Posts.Add(post);
                    }

                    session.SaveOrUpdate(user);
                }
                transaction.Commit();
            }

            foreach (User u in session.CreateCriteria(typeof (User)).List<User>())
            {
                Console.WriteLine(u);
                foreach (Post post in u.Posts)
                {
                    // post.User is always null!
                    Console.WriteLine("  {0}", post);
                }
            }

            foreach (Post p in session.CreateCriteria(typeof(Post)).List<Post>())
            {
                // p.User is always null!
                Console.WriteLine(p);
            }
        }
    }

Post.User始终为null。已经花了3个小时。我哪里错了?

1 个答案:

答案 0 :(得分:1)

  1. 您从未设置Post.User属性且User.Posts集合是反向的,因此不会在数据库中创建引用(如果posts.UserId列不为null,您将得到一个插入时出错。。
  2. 您仍处于同一会话中,因此即使User.Posts集合是非反向的,Post.User属性仍为空。 NHibernate不会在保存时修改您的对象(除了用自己的实现替换集合),并且条件返回您刚刚保存的相同对象,因为它们位于会话缓存中。