NHibernate - дочерний объект нулевой - PullRequest
0 голосов
/ 03 октября 2009

Использование NHibernate 2.0, атрибутов класса NHibernate для сопоставлений, ASP.NET MVC для создания приложения типа доски объявлений.

У меня есть 2 объекта: почта и пользователь. Post имеет свойство Owner, которое является экземпляром User. Он также имеет свойство Replies, которое является коллекцией типа ISet.

Идея состоит в том, что одно сообщение может иметь один уровень ответов, такой же, как сообщение SO с комментариями. Моя страница MVC использует частичное представление (типа Mvc.ViewUserControl) для отображения постов верхнего уровня (родительских). Частичное представление ParentPost, в свою очередь, использует частичное представление ChildPost (также типа Mvc.ViewUserControl) для отображения ответов (различная разметка отображения для ответов).

Все отлично работает, за исключением того, что экземпляры Owner типа User являются нулевыми в коллекции ответов. Они прекрасно загружаются в родительскую коллекцию.

Другими словами, на родительском уровне все свойства загружены правильно, включая владельца сообщения. В коллекции «Ответы» сообщения с ответами загружаются со всеми свойствами, кроме их владельцев. Для чего это стоит, Владелец - единственное свойство класса Почты.

Может ли кто-нибудь помочь мне понять, как заставить NHibernate загрузить экземпляры Owner в коллекции ответов?

Вот соответствующее отображение для 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; }
}

Вот соответствующее отображение для пользователя:

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

1 голос
/ 04 октября 2009

Для Post.Owner вы должны сопоставить его со многими к одному. Мой пример в XML

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

Отображение один-к-одному предполагает, что два объекта имеют одинаковое значение идентификатора. Еще один момент, на который следует обратить внимание: ForeignKey в NH Mapping означает имя FK, а не столбец внешнего ключа.

Дружеское замечание: вам не нужны свойства OwnerId и Owner. Все, что вам нужно, это просто собственность владельца. Вам также не нужно свойство ParentId, но убедитесь, что вы установили Inverse = false для Post.Replies

Полный пример:

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...