1

我在尝试为以下情况编写查询时遇到了巨大的困难:

在我的核心框架中(我无法修改,因为它不是我们的代码)我有两个类:

[Class(Table = "Teacher")]
public class Teacher
{
    [Id]
    public virtual long? Id {get;set;}

    [Property]
    public virtual string EmployeeNr{get;set;}
}

[Class(Table = "Student")]
public class Student
{
    [Id]
    public virtual long? Id{get;set;}

    [Property]
    public virtual string Name{get;set;}
}

接下来,在我的应用程序层中,我创建了以下类来记录有关学生和教师进行测试的信息

[Class(Table = "TestReports", DiscriminatorValueObject = 1)]
public class TestReport
{
    [Id]
    public virtual long? Id{get;set;}

    [Property]
    public virtual string TestName{get;set;}

    [Property]
    public virtual DateTime Date{get;set;}

    [Property]
    public virtual int Correct{get;set;}

    [Property]
    public virtual int InCorrect{get;set;}

    [Property]
    public virtual int Unanswerd{get;set;}

}

[Subclass(NameType = typeof(StudentTestReport), ExtendsType = typeof(TestReport), DiscriminatorValueObject = 2)]
public class StudentTestReport
{
    [ManyToOne]
    public virtual Student Student{get;set;}
}

[Subclass(NameType = typeof(TeacherTestReport), ExtendsType = typeof(TestReport), DiscriminatorValueObject = 3)]
public class TeacherTestReport
{
    [ManyToOne]
    public virtual Teacher Teacher{get;set;}
}

现在我想要的是一个查询来获取所有学生和老师的最后一个测试报告但是如果老师或学生没有参加任何测试,他们仍然应该出现在概览中。所以我决定采用 AliasToBeanTranformer 方法并为报表创建一个包装器对象:

public class TestOverviewWrapper
{
    public virtual string TestName{get;set;}
    public virtual DateTime Date{get;set;}
    public virtual int Correct{get;set;}
    public virtual int InCorrect{get;set;}
    public virtual int Unanswerd{get;set;}
    public virtual long Id{get;set;}
    public virtual string Name{get;set;}
    public virtual string EmployeeNr{get;set;}

    public virtual string Person
    {
            get{ return Name ?? EmployeeNr;}
    }
}

我在正确查询时遇到了很大的麻烦,我试图看看我是否只能得到学生和他们的最后一个测试报告,但是我卡住了将子查询的属性投影到包装器对象中。这是我走了多远:

public IList<TestOverviewWrapper> GetTestOverview()
{
    var crit = SessionFactory.GetCurrentSession().CreateCriteria<Student>("st");

    var dcrit = DetachedCriteria.For<StudentTestReport>("lastTest")
        .Add(Subqueries.PropertyEq("Date",
                                   DetachedCriteria.For<StudentTestReport>("test")
                                       .Add(Restrictions.EqProperty("lastTest.Student", "st.Id"))
                                       .SetProjection(Projections.Max("lastTest.Date"))));

    dcrit.Add(Restrictions.EqProperty("lastTest.Student", "st.Id"));

    crit.Add(Subqueries.Select(dcrit));

    crit.SetProjection(Projections.ProjectionList()
                            .Add(Projections.Property("lastTest.Id")
                            .Add(Projections.Property("lastTest.TestName")
                            .Add(Projections.Property("lastTest.Date")
                            .Add(Projections.Property("lastTest.Correct")
                            .Add(Projections.Property("lastTest.Incorrect")
                            .Add(Projections.Property("lastTest.Unanswerd")
                            .Add(Projections.Property("st.Id")
                            .Add(Projections.Property("st.Name")
                        );

    crit.SetResultTransformer(Transformers.AliasToBean<TestOverview>());
    return crit.List<TestOverviewWrapper>();
}

谁能指出我正确的方向,记住我不能在学生和教师班级上添加映射

4

1 回答 1

1

有一个名为 Future 的方便功能可以一起批量选择。鉴于以下

public class TestOverviewWrapper
{
    public virtual string TestName { get; set; }
    public virtual DateTime Date { get; set; }
    public virtual int Correct { get; set; }
    public virtual int InCorrect { get; set; }
    public virtual int Unanswerd { get; set; }
    public virtual long Id { get; set; }
    public virtual string Person { get; set; }
}

查询(IES)看起来像

var studentTests = session.CreateCriteria<StudentTestReport>("test")
    .Add(Subqueries.PropertyEq("Date", DetachedCriteria.For<StudentTestReport>()
        .Add(Restrictions.EqProperty("Student", "test.Student"))
        .SetProjection(Projections.Max("lastTest.Date"))))
    .CreateAlias("Student", "student")
    .SetProjection(Projections.ProjectionList()
        .Add(Projections.Property("TestName"), "TestName")
        .Add(Projections.Property("Date"), "Date")
        .Add(Projections.Property("Correct"), "Correct")
        .Add(Projections.Property("Incorrect"), "Incorrect")
        .Add(Projections.Property("Unanswerd"), "Unanswerd")
        .Add(Projections.Property("student.Id"), "Id")
        .Add(Projections.Property("student.Name"), "Person"))
    .SetResultTransformer(Transformers.AliasToBean<TestOverviewWrapper>())
    .Future<TestOverviewWrapper>();

var studentsWithoutTests = session.CreateCriteria<Student>("student")
    .Add(Subqueries.NotExists(DetachedCriteria.For<StudentTestReport>()
        .Add(Restrictions.EqProperty("Student", "student"))))
    .SetProjection(Projections.ProjectionList()
        .Add(Projections.Property("Id"), "Id")
        .Add(Projections.Property("Name"), "Person"))
    .SetResultTransformer(Transformers.AliasToBean<TestOverviewWrapper>())
    .Future<TestOverviewWrapper>();

var teacherTests = session.CreateCriteria<TeacherTestReport>("test")
    .Add(Subqueries.PropertyEq("Date", DetachedCriteria.For<TeacherTestReport>()
        .Add(Restrictions.EqProperty("Teacher", "test.Teacher"))
        .SetProjection(Projections.Max("lastTest.Date"))))
    .CreateAlias("Teacher", "teacher")
    .SetProjection(Projections.ProjectionList()
        .Add(Projections.Property("TestName"), "TestName")
        .Add(Projections.Property("Date"), "Date")
        .Add(Projections.Property("Correct"), "Correct")
        .Add(Projections.Property("Incorrect"), "Incorrect")
        .Add(Projections.Property("Unanswerd"), "Unanswerd")
        .Add(Projections.Property("teacher.Id"), "Id")
        .Add(Projections.Property("teacher.EmployeeNr"), "Person"))
    .SetResultTransformer(Transformers.AliasToBean<TestOverviewWrapper>())
    .Future<TestOverviewWrapper>();

var teacherWithoutTests = session.CreateCriteria<Teacher>("teacher")
    .Add(Subqueries.NotExists(DetachedCriteria.For<TeacherTestReport>()
        .Add(Restrictions.EqProperty("Teacher", "teacher"))))
    .SetProjection(Projections.ProjectionList()
        .Add(Projections.Property("Id"), "Id")
        .Add(Projections.Property("EmployeeNr"), "Person"))
    .SetResultTransformer(Transformers.AliasToBean<TestOverviewWrapper>())
    .Future<TestOverviewWrapper>();

return studentTests.Concat(studentsWithoutTests).Concat(teacherTests).Concat(teacherWithoutTests);
于 2012-08-14T09:08:29.083 回答