Это - проблема однонаправленного непосредственного отображения в NHibernate.
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; }
}
public class StudentDetail
{
public int ID { get; set; }
public string Father { get; set; }
public string Mother { get; set; }
}
Как я могу отобразить эти классы (как hbm отображающиеся файлы похожи) к следующему случаю непосредственных отношений?
Взгляните на классы и таблицу очень тщательно.
Куда я могу поместить <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
. Поскольку, StudentDetail.cs
не содержит свойства типа Student
.
Я могу использовать <one-to-one>
- тег? Если да, куда я должен поместить его, в Student.cs
или StudentDetail.cs
? И как я должен настроить его?
Вы можете отобразить его как один-ко-многим, со скрытым свойством коллекции и публичным открытием только его первого элемента:
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.
Случай #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