NHibernate - 展平系列

时间:2015-11-22 00:09:44

标签: c# nhibernate nhibernate-mapping queryover

我有一个包含集合的对象:

public class Teacher
{
    public virtual string Name {get;set;}
    public virtual ISet<Student> Students {get;set;}
    // ...
}

public class Student
{
    public virtual string LastName {get;set;}
    // ... 
}

DetachedCriteria类型&#34;老师&#34;正确填充&#34;教师&#34;带有映射学生集合的对象。

示例:

如果老师&#39; X&#39;包含3名学生&#39; A&#39;&#39; B&#39;并且&#39; C&#39;:返回一个对象(&#39;教师&#39;),其中包含3个对象的集合(学生&#39; A&#39;&#39; B&#39;和&#39; C&#39;)。

映射配置为:

<class table="Teacher" name="...">
    <id name="Id" ... />
    <property name="Name" column="Name" />
    <set name="Students" table="Student" inverse="true">
        <key column="TeacherId" />
        <one-to-many class="Student" />
    </set>
</class>

我想从数据库中检索一行/学生。 我创建了一个新课程如下:

public class TeacherWithFlattenCollection
{
    public virtual string Name {get;set;} // The name of the teacher
    public virtual string  LastName {get;set;} // The name of the student
}

映射配置为:

<class table="Teacher" name="...">
    <id name="Id" ... />
    <property name="Name" column="Name" />
    <join table="Student" fetch="join">
        <key column="TeacherId" />
        <property name="LastName" column="LastName" />
    </join>
</class>

通过为DetachedCriteria使用这个新类,我收到了正确数量的项目,但它们没有正确填充:

  • 姓名=&#39; X&#39;,姓氏=&#39; A&#39;
  • 姓名=&#39; X&#39;,姓氏=&#39; A&#39;
  • 姓名=&#39; X&#39;,姓氏=&#39; A&#39;

而不是:

  • 姓名=&#39; X&#39;,姓氏=&#39; A&#39;
  • 姓名=&#39; X&#39;,姓氏=&#39; B&#39;
  • 姓名=&#39; X&#39;,姓氏=&#39; C&#39;

我是否遗漏了映射配置中的某些内容?

1 个答案:

答案 0 :(得分:0)

我没有回答如何正确调整标准NHibernate的使用 - 如上所述。但我可以分享我(希望其他人也会如此)这样做。

ORM的基础是双向映射。它在DB中是双向的,因此它也应该在C#中:

// as is
public class Teacher
{
    public virtual ISet<Student> Students {get;set;}
    // ...
}

// has reference to Teacher
public class Student
{
    public virtual Teacher Teacher {get;set;}
    // ... 
}

学生扩展映射:

<class table="Student" name="...">
    <id name="Id" ... />
    ...
    <many-to-one name="Teacher" column="TeacherId" ... />
</class>

BTW:现在,现在,我们可以使用inverse =&#34; true&#34;在教师方面,因为我们可以将控制权反转给学生。这意味着,我们总是应该/必须分配双方

var student = ...;
var teacher = ...;
teacher.Students.Add(student);
student.Teacher = teacher; // this is the ONLY way how to use inverse

查询:现在我们可以使用简单的查询 - 从学生方面:

// aliasing to support type safe access to properties
Teacher teacher = null;
Student student = null;
TeacherWithFlattenCollection dto = null;

// now we query from Student side, to get proper data    
var query = session.QueryOver<Student>(() => student)
    .JoinAlias(x => x.Teacher, () => teacher)
    .Where(...)
    .SelectList(list => list
           .Select(x => x.LastName)    .WithAlias(() => dto.LastName)
           .Select(x => x.Teacher.Name).WithAlias(() => dto.Name)
    )
    .TransformUsing(Transformers.AliasToBean<TeacherWithFlattenCollection >())

注意:(我们不需要像上面那样使用DTO,请查看如何使用一点help of this transformer - 请在此处阅读更多内容:How to partially project a child object with many fields in nHibernate