教师与学生一对一。
SpecialTeacher扩展了Teacher,但专门针对SpecialStudents。
在层次结构中使用每个类的表。
public class Teacher
{
public virtual int Id { get; set; }
public virtual int DepartmentId { get; set; }
public virtual String Name { get; set; }
public virtual Student Student { get; set; }
}
public class SpecialTeacher : Teacher
{
public virtual string TelephoneNumber { get; set; } //SpecialTeachers get to have a phone
public virtual SpecialStudent SpecialStudent { get { return (SpecialStudent)base.Student; } set { Student = value; } }
}
public class Student
{
public virtual int Id { get; set; }
public String Name { get; set; }
}
public class SpecialStudent : Student
{
public int SpecialMark { get; set; }
}
以及相关的映射:
<class name="Student">
<id name="Id" />
<property name="Name" />
</class>
<joined-subclass name="SpecialStudent" extends="Student">
<key column="Id" />
<property name="SpecialMark" />
</joined-subclass>
<class name="Teacher">
<id name="Id" />
<property name="DepartmentId" />
<property name="Name" />
<many-to-one name="Student" column="StudentId" />
</class>
<joined-subclass name="SpecialTeacher" extends="Teacher">
<key column="Id" />
<property name="TelephoneNumber" />
</joined-subclass>
所以,让我们说我们希望得到特定部门的SpecialStudents的平均分数:
public double GetAverageScoreForSpecialStudentsByDepartment(int departmentId)
{
return CurrentSession.Query<SpecialTeacher>()
.Where(st => st.DepartmentId == departmentId)
.Average(ss => ss.SpecialStudent.SpecialMark);
}
测试将失败,因为它会抱怨SpecialStudent不是SpecialTeacher的映射属性。
我能想到避免此问题的唯一方法是映射属性,但这是重复的,因为基础教师已经映射到学生层次结构。
更新
我还想提一下,之前我们将SpecialTeacher设置为:
public class SpecialTeacher : Teacher
{
public virtual string TelephoneNumber { get; set; } //SpecialTeachers get to have a phone
public virtual new SpecialStudent Student { get { return (SpecialStudent)base.Student; } set { Student = value; } }
}
确实看起来没问题,但是在检索审计数据时,Envers没有使用它。
答案 0 :(得分:1)
我能想到避免此问题的唯一方法是映射属性,但这是重复的,因为基础教师已经映射到学生层次结构。
这不是重复,因为您从未在SpecialStudent
映射文件中映射SpecialTeacher
属性。虽然您在代码中正确定义了关系,但NHibernate无法知道SpecialTeacher
假设有SpecialStudent
。 NHibernate使用代码从表中重新创建对象,但前提是您在映射中定义了正确的关系。
请记住,BaseTeacher
与BaseStudent
并不意味着SpecialTeacher
与SpecialStudent
的关系。