我自己也遇到了这个。在我的情况下,问题是查询有一个 .Select() 子句,该子句导致建立进一步的关系,最终进一步过滤查询,因为关系内部连接约束了结果。
似乎 .Count() 不处理查询的 .Select() 部分。
所以我有:
// projection created
var ordersData = orders.Select( ord => new OrderData() {
OrderId = ord.OrderId,
... more simple 1 - 1 order maps
// Related values that cause relations in SQL
TotalItemsCost = ord.OrderLines.Sum(lin => lin.Qty*lin.Price),
CustomerName = ord.Customer.Name,
};
var count = ordersData.Count(); // 207
var count = ordersData.ToList().Count // 192
当我比较 SQL 语句时,我发现 Count() 对 Orders 表执行了一个非常简单的 SUM,它返回所有订单,而第二个查询是 100 多行 SQL 的怪物,其中有 10 个由 . Select() 子句(检索到的相关值/聚合比此处显示的要多)。
基本上,这似乎表明 .Count() 在计算时没有考虑 .Select() 子句,因此不会为 .Count() 触发那些导致进一步约束结果集的相同关系。
我已经能够通过向 .Count() 方法显式添加表达式来完成这项工作,该方法将一些聚合结果值拉入,这些结果值也有效地强制它们进入 .Count() 查询:
var count = ordersData.Count( o=> o.TotalItemsCost != -999 &&
o.Customer.Name != "!@#"); // 207
关键是确保计算或提取相关数据并导致关系触发的任何字段都包含在强制 Count() 在其查询中包含所需关系的表达式中。
我意识到这是一个彻底的黑客攻击,我希望有更好的方法,但目前这至少使我们能够获得正确的价值,而无需首先使用 .ToList() 拉下大量数据。