Двунаправленный один-ко-многим в NHibernate - PullRequest
0 голосов
/ 20 сентября 2011

Вот сопоставления:

<?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 Ответ

1 голос
/ 20 сентября 2011
  1. Вы никогда не устанавливаете свойство Post.User, а коллекция User.Posts является обратной, поэтому в базе данных не будет создаваться ссылка (если столбец posts.UserId не будет нулевым, вы получите ошибку при вставке).
  2. Вы все еще находитесь в том же сеансе, поэтому, даже если коллекция User.Posts не является обратной, свойство Post.User все равно будет иметь значение null. NHibernate не изменяет ваши объекты при сохранении (кроме замены коллекций собственными реализациями), и критерии возвращают те же самые объекты, которые вы только что сохранили, поскольку они находятся в кэше сеанса.
...