Как сделать это однонаправленное сопоставление NHibernate один-к-одному? - PullRequest
7 голосов
/ 07 июня 2010

Это проблема однонаправленного однозначного сопоставления в NHibernate.

Student.cs

public class Student
{
    public int ID { get; set; }
    public int Roll { get; set; }
    public int RegNo { get; set; }
    public string Name { get; set; }

    public StudentDetail StudentDetail { get; set; }
}

StudentDetail.cs

public class StudentDetail
{
    public int ID { get; set; }

    public string Father { get; set; }
    public string Mother { get; set; }
}

Как можно сопоставить эти классы (как выглядят файлы отображения hbm) в следующем случае отношения один-к-одному?

alt text

Пожалуйста, внимательно посмотрите на классы и таблицу.

Где можно поместить тег <many-to-one> в Student.hbm.xml или StudentDetail.hbm.xml? Если я введу его в Student.hbm.xml, как я могу отобразить столбец StudentDetail.StudentID, потому что он находится в другой таблице?

Итак, это отображение:

<class name="Student" table="Student">
    <id name="ID" column="ID">
      <generator class="native"/>
    </id>

    .......

    <many-to-one class="StudentDetail" name="StudentDetail" column="StudentID" unique="true" cascade="all" />
  </class>

генерирует следующее исключение:

{"Invalid column name 'StudentID'."}

С другой стороны, <many-to-one> нельзя поместить в StudentDetail.hbm.xml. Coz, StudentDetail.cs не содержит никакого свойства типа Student.

Могу ли я использовать <one-to-one> -tag? Если да, куда мне его поместить, в Student.cs или StudentDetail.cs? И как мне это настроить?

Ответы [ 2 ]

5 голосов
/ 07 июня 2010

Дело № 1:

В студенческом ...

<one-to-one name="StudentDetail" 
            cascade="save-update,delete" 
            property-ref="Student" />

В StudentDetail ...

<many-to-one name="Student" 
             column="StudentID" 
             unique="true" 
             cascade="none" />

Обратите внимание, что у вас должно быть свойство в классе StudentDetail, которое ссылается на объект Student (называется Student). Кроме того, ваши каскады могут отличаться в зависимости от вашего использования. Вы, скорее всего, хотите, чтобы там был каскад удаления.

unique="true" обеспечивает взаимно-однозначное сопоставление на стороне StudentDetail.

Дело № 2:

Просто поменяйте два сопоставления, убедившись, что вы изменили имена свойств на противоположный класс.

Смотрите здесь для получения дополнительной информации: http://nhforge.org/blogs/nhibernate/archive/2009/04/19/nhibernate-mapping-lt-one-to-one-gt.aspx

2 голосов
/ 07 июня 2010

Вы можете отобразить его как один-ко-многим, со скрытым свойством коллекции и открытым для общественности только его первым элементом:

public class Student
{
    public virtual int ID { get; set; }
    public virtual int Roll { get; set; }
    public virtual int RegNo { get; set; }
    public virtual string Name { get; set; }

    protected virtual IList<StudentDetail> StudentDetails { get; set; }

    public virtual StudentDetail StudentDetail
    {
        get
        {
            if (StudentDetails.Count == 0) return null;
            return StudentDetails[0];
        }
        set
        {
            if (StudentDetails.Count != 0) throw new Exception();
            StudentDetails.Add(value);
            value.Student = this;
        }
    }
}

Вы могли бы справиться с установщиком лучше, чем этот - главное, чтобы вы не добавляли несколько строк в один-ко-многим. Очевидно, в этом случае StudentDetails отображается, но StudentDetail отсутствует в ваших .hbm.xml или Fluent отображениях.

...