0

老师与学生一对一。

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 在检索审计数据时没有使用它。

4

1 回答 1

1

我能想到避免这个问题的唯一方法是映射属性,但这是重复的,因为基础教师已经映射到学生层次结构。

这不是重复,因为您从未在映射文件中映射该SpecialStudent属性。SpecialTeacher尽管您在代码中正确定义了关系,但 NHibernate 无法知道 aSpecialTeacher是否应该具有SpecialStudent. NHibernate 使用该代码从表中重新创建对象,但前提是您在映射中定义了正确的关系。

请记住,BaseTeachertoBaseStudent并不意味着SpecialTeacher关系SpecialStudent

于 2013-01-16T15:25:01.727 回答