在NHibernate中加入子查询(连接多个列)

时间:2013-08-21 16:55:11

标签: c# nhibernate join

如何表达查询

    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语法中?

因此,我希望从items表中获取每个名称的最大日期记录。

表格中的每个项目都对应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>();

但我不知道如何编写连接,因为我无法找到如何使用JoinQueryOver()来表达两个实体之间的连接(在我的情况下是ItemLatest和ItemEnity),没有关系属性引用从一个到另一个。

1 个答案:

答案 0 :(得分:1)

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

我们可以做的是创建一个新对象,例如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#ItemEnityMaxDateItemEntity类似(我们只需要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>();

这可能不是唯一的方法。但是这样,将您的“特殊查询”表示为对象......将起作用