SQL中的统计查询 - NHibernate LINQ可以实现吗?

Run*_*sen 8 sql linq nhibernate linq-to-nhibernate

我有一个应用程序,它使用一些数据仓库原则,如维度建模,在一个相当简单的数据库上进行报告.

名为Call的示例(简化)实体如下所示:

    public virtual long Id { get; set; }
    public virtual string OriginatorNumber { get; set; }
    public virtual string DestinationNumber { get; set; }
    public virtual DateDimension DateDimension { get; set; }
Run Code Online (Sandbox Code Playgroud)

实际模型的一些属性已被删除,因为它们无关紧要.简化的DateDimension如下所示:

    public virtual long Id { get; set; }
    public virtual DateTime Date { get; set; }
    public virtual int DayOfMonth { get; set; }
    public virtual int Weekday { get; set; }
Run Code Online (Sandbox Code Playgroud)

还有很多这样的专栏 - 它们通过应用程序设置预先填充了当前十年.因此,整个十年中的每个日期在此表中都有一行,每个调用都有一个指向它发生日期的链接.这全部映射在Fluent NHibernate并且工作正常.

如果我想做一些报告,我可以使用3.0中改进的NHibernate LINQ提供程序轻松完成.我们希望使用LINQ来提高我们提供的可维护性,但如果我们真的必须,我们将考虑HQL,ICriteria甚至纯SQL.

所以说我想建立一个报告,显示来自某个数字的呼叫数量除以它们发生的星期几.我可以这样轻松地做到这一点:

        var query = Calls
            .Where(c => c.OriginatorNumber == "402")
            .GroupBy(c => c.DateDimension.Weekday)
            .Select(g => new { Day = g.Key, Calls = g.Count() } );
Run Code Online (Sandbox Code Playgroud)

在此示例中,"Calls"基本上是通过存储库接口从NHibernates LINQ提供程序(Query)返回的IQueryable.上面的查询给出了正确的结果,NHibernate Profiler向我展示了SQL非常优秀,一切都很好.

但是,如果我想做一些更先进的事情,我会陷入困境.假设我想要每个工作日的平均呼叫次数.离上面不太远吧?我只需要弄清楚每个工作日在结果集中的唯一日期数,除以它的总呼叫次数,我们都设置好了 - 对吗?嗯,不,这是我开始遇到NHibernate LINQ提供程序的限制的地方.使用LINQ to对象,我可以构造一个查询来执行它 - 有些东西

.Select(g => g.Count() / g.GroupBy(c => c.DateDimension.Date).Count());
Run Code Online (Sandbox Code Playgroud)

但是,在NHibernate中使用它时,这不会转换为正确的查询.相反,它将上面的.Count()调用转换为相同的调用记录数(*),因此结果始终为1.

我当然可以查询每个调用,工作日和日期作为一个新的匿名对象,然后在应用程序方面进行数学运算,但根据传统观点,那是错误的(t​​m).我最终可能会绝望地做到这一点,甚至当桌子增长到一百万个++电话时,这意味着痛苦.

下面是一个SQL查询,它给出了我正在寻找的结果.

select ss.Weekday, AVG(cast(ss.Count as decimal))
from
(
select dd.Weekday, dd.Date, COUNT(*) as Count
from Call c
left outer join DateDimension dd
    on c.DateDimension_id = dd.Id
where c.OriginatorNumber = '402'
group by dd.Weekday, dd.Date
) ss
group by ss.Weekday
order by ss.Weekday
Run Code Online (Sandbox Code Playgroud)

是否可以使用NHibernate LINQ提供程序执行此操作?或者,如果这是不可能的,在我必须让应用程序获取中间结果并完成剩下的工作之前,我能有多接近?

cbp*_*cbp 1

有很多事情无法通过 LINQ 提供程序完成。对于 NHibernate,您必须接受使用 HQL 或 CreateCriteria。

我还没有尝试过,但看起来您应该能够使用 HQL 或 CreateCriteria (使用 DetatchedCriteria)做您想做的事情。

如果您绝望,您还可以使用 CreateSqlQuery 退回到纯 SQL。