2

我一直在为即将到来的项目评估 NHibernate,并正在研究一些用例以了解它的性能。我还没有找到一种方法来使用 Criteri API 来表达以下查询。

两个相当基本的表格(为了这个例子的目的而减少)

CREATE TABLE Person
(
    PersonNo  INT,
    BirthDate DATETIME
)

CREATE TABLE PersonDetails
(
    PersonNo  INT,
    FirstName VARCHAR(30),
    Surname   VARCHAR(30)
)

而查询...

SELECT P.PersonNo, P.FirstName, P.Surname
FROM Persons P
JOIN PersonDetails PD
  ON PD.PersonNo = P.PersonNo
 AND EffDate =
    (
        SELECT MAX(EffDate)
        FROM PersonDetails
        WHERE PersonNo = PD.PersonNo
    )
WHERE P.PersonNo = 1

基本上,我只是想将人员主记录和最新的人员修订记录扁平化为一个对象。我可以使用 HQL 轻松完成此操作,但无法使相关子查询正常工作。

这是我的尝试。

var pdSub = DetachedCriteria.For<PersonRevision>("pdSub")
    .SetProjection(
        Projections.ProjectionList()
            .Add(Projections.Max("EffDate").As("MaxEffDate"))
            .Add(Projections.Property("Person.PersonNo").As("PersonNo")) 
            .Add(Projections.GroupProperty("Person.PersonNo")))
    .Add(Expression.EqProperty("pdSub.Person.PersonNo", "p.PersonNo"));    

var p =
    session.CreateCriteria<Person>("p")                                                
        .Add(Restrictions.Eq("p.PersonNo", 1))
        .Add(Subqueries.Eq("p.PersonNo", pdSub))
        .List();  

子查询 pdSub 已经定义了关系(通过 PersonNo),但是 Subqueries 类需要定义另一个关系(例如 Eq)?

任何帮助,将不胜感激。

谢谢,约翰

4

1 回答 1

5

出于演示的目的,我已将 EffDate 添加到两个表中。希望这与您的模型相匹配并适当地演示这种连接。

DetachedCriteria subQuery = DetachedCriteria
    .For<PersonDetails>("pd")
    .SetProjection(Projections.Max("pd.EffDate"))
    .Add(Restrictions.EqProperty("pd.PersonId", "p.PersonId"));

IList results = Session
    .CreateCriteria(typeof(Person), "p")
    .SetProjection(Projections.ProjectionList()
        .Add(Projections.Property("p.PersonId").As("PersonId"))
        .Add(Projections.Property("p.EffDate").As("MaxEffDate")))
    .Add(Subqueries.PropertyEq("p.EffDate", subQuery))
    .List();

SQL NHibernate 在服务器上抛出看起来像这样......

SELECT this_.PersonId as y0_, this_.EffDate as y1_ FROM Person this_ WHERE this_.EffDate = (SELECT max(this_0_.EffDate) as y0_ FROM PersonDetails this_0_ WHERE this_0_.PersonId = this_.PersonId)
于 2010-11-10T23:02:59.060 回答