查询层次结构到层次结构关系时出现问题

时间:2013-01-16 11:18:21

标签: nhibernate nhibernate-mapping linq-to-nhibernate

教师与学生一对一。

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没有使用它。

1 个答案:

答案 0 :(得分:1)

  

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

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

请记住,BaseTeacherBaseStudent并不意味着SpecialTeacherSpecialStudent的关系。