NHibernate中的双向一对多

本文关键字:一对多 NHibernate | 更新日期: 2023-09-27 18:09:09

映射如下:

<?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个小时了。我哪里错了?

NHibernate中的双向一对多

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