【问题标题】:Entity Framework - Get row count of a (group by Subquery)实体框架 - 获取(按子查询分组)的行数
【发布时间】:2014-11-11 20:38:50
【问题描述】:

我有这个简单的表达式来获取每个订单的金额:

public IQueryable<Orders> GetAccountSummery()
{
    return context.Orders.GroupBy(a => new { orderNo = a.orderNo })
   .Select(b => new 
   { 
   orderNo = b.Key.orderNo,
   amount = b.Sum(r => r.amount)
   });
}

我需要获取上一个表达式返回的记录总数:

SQL

select COUNT(1)  from 
(
 SELECT orderNo,SUM(amount) Amount  
FROM  Orders
group by orderNo
)tbl -- I get 125,000 row count here

EF

public int GetOrdersCount()
{
    return GetAccountSummery().Count(); // This guy here gives 198,000 rows which counts all rows from orders table
   // The following line gives the correct row count:
    return GetAccountSummery().AsEnumerable().Count(); // 125,000 row
}

GetAccountSummery().AsEnumerable().Count() 的问题在于它首先在服务器端运行查询然后在客户端计算正确的行数(请考虑此处的表大小)

有什么方法可以在不执行 select 语句的情况下只获得正确的计数?

编辑

如果 groupBy 子查询无法做到这一点,那为什么 Where 子查询可以做到这一点?

【问题讨论】:

    标签: c# sql-server entity-framework linq-to-entities


    【解决方案1】:

    您目前的结构方式是什么?不会。您将始终执行.Select()statement,因为.Count() 采用立即执行(请参阅here for a list)。但是,.Count() 也有一个覆盖 Func,您应该可以使用它来获取计数,而无需先执行选择,如下所示:

    context.Orders.GroupBy(a => new { orderNo = a.orderNo })
                  .Count(a => a.Key.orderNo != string.Empty);
    

    编辑:哎呀,忘了这是一个布尔值。相应地进行了编辑。

    编辑 2:根据 cmets,我认为这是不可能的,因为您总是需要在任何给定时间在那里进行选择,并且 .Count() 将始终调用它。对不起。

    【讨论】:

    • 我在 count func 上收到此消息:无法将类型 int 隐式转换为 bool,这意味着 count 参数应该是 bool
    • 因为 orderNoint 我试过 Count(a =&gt; a.Key.orderNo != 0) 我得到了同样的错误结果 198,000..
    • 奇怪的是,下面的 SQL 被执行了 :SELECT [GroupBy1].[A1] AS [C1] FROM ( SELECT COUNT(1) AS [A1] FROM [dbo].[Orders] AS [Extent1] WHERE 0 &lt;&gt; [Extent1].[orderNo] ) AS [GroupBy1] 仍然没有按 orderNo 分组
    • 没关系。谢谢兄弟帮忙
    猜你喜欢
    • 2021-02-27
    • 1970-01-01
    • 2019-07-21
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    相关资源
    最近更新 更多