单个LINQ to SQL查询中的SUM和COUNT

8
尝试在LINQ-TO-SQL中创建以下查询。
select count(*), sum( o.CostInCents ) from Orders o
where Flag = true;

我想到了下面的LINQ查询:
var q = db.Orders
    .Where(o => o.Flag )

var result = q
    .GroupBy(o => 1)
    .Select(g => new MyDTO
    {
        NoOfOrders = g.Count(),
        TotalInCents = g.Sum(o => o.CostInCents )
    })
    .SingleOrDefaultAsync();

有更好的方法吗?

.GroupBy(o => 1)是正确的吗?

另一种选择是执行两个查询,如下所示。

var q = db.Orders
   .Where(o => o.Flag );

//No groupBy
var result2 = new MyDTO
{
    NoOfCostedOrders = q.Count(),//hit the db
    TotalInCents = q.Sum(o => o.CostInCents )//hit the db 2nd time
};

我该如何判断哪种方法更好?

提前感谢!


就性能而言,我建议尽可能保持iqueryable的过滤功能,https://dev59.com/_XI-5IYBdhLWcg3w-92b#1578977 除此之外,我不太确定您想用代码实现什么。 - Niklas
你对订单的分组要求是什么,不太清楚,你想使用哪个属性? - Mrinal Kamboj
7
没问题。这个技巧被称为“常量分组”,是使用LINQ在单个数据库查询中生成多个聚合的唯一方式。 - Ivan Stoev
1
@IvanStoev 谢谢 :) - Mrinal Kamboj
@IvanStoev 刚刚审核了这个问题,https://dev59.com/Z3I-5IYBdhLWcg3w9tdw看起来它只是将所有数据作为单个单位进行分组,这样做有什么好处呢?我们没有它就无法轻松获取结果。 - Mrinal Kamboj
@MrinalKamboj 实际上这只是将一个集合转换为单个组的一种方式。其好处在于允许在LINQ查询中使用多个聚合函数,而该查询没有分组,因此通常会生成一个集合。 - Ivan Stoev
2个回答

4
This query can be rewritten in sql format as follows

var orderList = db.Orders.Where(o => o.Flag );
var orderSummary = from o in orderList
                   group o by 1 into p
                   select new
                   {
                      Items = p.Count(),
                      Total = p.Sum( x => x.CostInCents)
                   }

1
我认为您正在寻找的是以下微小调整:
var q = db.Orders
   .Where(o => o.Flag).Select(o => o.CostInCents).ToList(); // hit the db here once

//No groupBy
var result2 = new MyDTO
{
    NoOfCostedOrders = q.Count(), // don't hit the db
    TotalInCents = q.Sum() // don't hit the db a 2nd time
};

如果您对我的调整有疑问,请随时评论。

1
非常聪明...我投了+1。然而,问题在于如果你有成千上万条记录,它将返回那么多坏记录 - 非常糟糕。但是,伙计,你的思维超越了常规。我喜欢它! - Sam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接