运行子查询的NHibernate自定义IProjection

时间:2013-09-24 00:07:28

标签: c# sql-server nhibernate

说我有两张表如下:

MainTable (
    Id int,
    Name varchar(100)
)

RelatedTable (
    Id int,
    Value int,
    MainTableId int -- foreign key
)

MainTableRelatedTable之间存在一对多关系,因此RelatedTable.MainTableId引用MainTable.Id

我想按照以下方式使用自定义IProjection

sess.CreateCriteria<MainTable>()
    .SetProjection(
        Projections.ProjectionList()
            .Add(Projections.Property("Id"))
            .Add(Projections.Property("Name"))
            .Add(new SumOfValuesProjection(/* arguments??? */))
    )
    .List();

生成以下SQL:

select
    Id,
    Name,
    -- how to get this sub-query from IProjection?
    (select sum(Value)
    from RelatedTable
    where RelatedTable.MainTableId = MainTable.Id) as SumOfValues
from MainTable

这只是我想要做的一个小例子。就我而言,可能有数十个这些子查询列。它们都使用聚合函数,但可能并非都使用sum()

我希望创建一个自定义IProjection,但我不太清楚从哪里开始。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

也许不是确切的答案,但可能更直接。我想展示一下,如何使用当前的NHibernate功能来根据需要执行类似的SQL。

诀窍不在自定义IProjection中,而是在对现有功能强大的 IProjection 实施的调用中:Projections.SubQuery

var criteria = CreateCriteria<MainTable>("Main")
    .SetProjection(
        Projections.ProjectionList()
            .Add(Projections.Property("Id"))
            .Add(Projections.Property("Name"))

            // here we go, let's profit from existing IProjection
            .Add(Projections.SubQuery(
                   DetachedCriteria
                       .For<RelatedTable>("Related")
                       .SetProjection(Projections.Sum("Value"))
                       .Add(Restrictions.EqProperty("Main.Id", "Related.MainTableId")))
                   , "value")
                )
     ...
     ;

如果这种方法还不够,我建议观察当前NHibernate代码中如何实现此功能。 因为仍然 - NHibernate是开源的......