在NHibernate中联接子查询(在多列上联接)

本文关键字:NHibernate 查询 | 更新日期: 2023-09-27 18:28:27

如何表达查询

    Select * from
        (select name, Max(date) as date from items group by name) as latest
    inner join items as i
        on i.name=latest.name and i.date = latest.date

在NHibernate的QueryOver语法中?

因此,我希望从项目表中获得每个名称的最长日期记录。

表中的每个项目对应于ItemEnity类:

[Class(Table = "items")]
public class ItemEnity
{
    [Id(Name = "Id")]
    [Generator(1, Class = "native")]
    public virtual long Id { get; set; }
    [Property(NotNull = true)]
    public virtual string Name { get; set; }
    [Property(NotNull = true)]
    public virtual DateTime Date { get; set; }
    // other columns ... 
}

我已经设法用强类型的形式表达了子查询:

public class ItemLatest
{
    public string Name { get; set; }
    public DateTime Date { get; set; }
}
// ...
ItemLatest latest = null;
var subquery = QueryOver.Of<ItemEntity>().SelectList(list => list
    .SelectGroup(i => i.Name).WithAlias(() => latest.Name)
    .SelectMax(i => i.Date).WithAlias(() => latest.Date))
    .TransformUsing(Transformers.AliasToBean<ItemLatest>());
var result = subquery.GetExecutableQueryOver(session).List<ItemLatest>();

但我不知道如何编写join,因为我找不到如何使用JoinQueryOver()来表示两个实体(在我的例子中是ItemLatest和ItemEnity)之间的连接,这两个实体之间没有从一个实体到另一个实体的关系属性引用。

在NHibernate中联接子查询(在多列上联接)

JOIN位于通过映射定义的ORM世界(包括NHibernate)中。因此,如果您想使用条件和JOIN,它必须位于References属性之上。

例如,我们可以做的是创建一个新对象,例如ItemEnityMaxDate,并将其映射到类似于SELECT MAX的视图。。GROUP BY。我们可以这样扩展它,例如:

SELECT main.Id, main.Name, main.Date
  FROM items  main
    INNER JOIN 
    (
      SELECT i.Name, Max(i.Date) AS Date FROM items i GROUP BY i.Name 
    ) AS latest
    ON main.Name = latest.Name AND main.Date = latest.Date

C#ItemEnityMaxDate将类似于ItemEntity(我们只需要Id),映射到上面的视图。然后我们可以将其用作子查询

// inner select
var subquery = DetachedCriteria.For<ItemEnityMaxDate>()
    .SetProjection(Projections.Property("Id"));
// the ItemEntity
var query = session.CreateCriteria<ItemEntity>()
    .Add(Subqueries.PropertyIn("Id", subquery));
var list = query.List<ItemEntity>();

这可能不是唯一的方法。但通过这种方式,将您的"特殊查询"表示为对象。。。将工作