Domanda

A Teacher has a one-to-one with a Student.

A SpecialTeacher extends Teacher but deals specifically with SpecialStudents.

Using table per class in the hierarchies.


    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; }
    }

and the associated mappings:

<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>

So, let's say that we want to get the average mark for SpecialStudents for a given department:

    public double GetAverageScoreForSpecialStudentsByDepartment(int departmentId)
    {
        return CurrentSession.Query<SpecialTeacher>()
            .Where(st => st.DepartmentId == departmentId)
            .Average(ss => ss.SpecialStudent.SpecialMark);
    }

The test will fail because it will complain that SpecialStudent is not a mapped property of SpecialTeacher.

The only way that I can think of avoiding this issue is to map the property, but this is duplication since the base Teacher is already mapped to the Student hierarchy.

Update

I meant to also mention that previously we had the SpecialTeacher set up like:

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; } }
}

which did appear to work ok, but Envers did not work with it when retrieving audited data.

È stato utile?

Soluzione

The only way that I can think of avoiding this issue is to map the property, but this is duplication since the base Teacher is already mapped to the Student hierarchy.

This is not duplication as you never mapped the SpecialStudent property in the SpecialTeacher mapping file. Although you correctly defined the relationship in code, NHibernate has no way of knowing a SpecialTeacher is suppose to have a SpecialStudent. The code is use by NHibernate to recreate the object from the tables, but only if you define the correct relationships in your mapping.

Remeber that BaseTeacher to BaseStudent does not imply SpecialTeacher to SpecialStudent relationship.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top