lee*_*n3o 3 linq-to-entities entity-framework entity-framework-6
我有一个查询的以下部分(这是一个更大的查询的结尾 - queryBuilder 是一个 IQueryable)
var results = queryBuilder
.OrderBy(x => x.Vehicle.RangeId)
.ThenBy(x => x.Rate.Rental)
.GroupBy(x => x.Vehicle.RangeId)
.Select(x => x.FirstOrDefault())
.OrderBy(x => x.Rate.Rental);
Run Code Online (Sandbox Code Playgroud)
它使用带有 Vehicle 对象和 Rental 对象的对象。大约有 12,000 辆车,分为大约 40 个范围(RangeId - Indexed int 指示)。
上面的查询工作正常,但是不符合我的预期。我希望它先按 RangeId 订购车辆,然后按租金(最低租金优先)。
然后按 RangeId 将它们分组并从组中选择第一个,这“应该”是最便宜的租金,因为它在调用 groupby 之前已被订购。
然而。它不是。它只是无序随机获得一个。有时它是第二便宜的。有时是第 5 次,依此类推。出于某种原因,GroupBy 不遵守原始订单!
通过执行以下操作,我可以使其正常工作。然而,表演绝对是可怕的,需要很长时间才能完成。
var results = queryBuilder
.OrderBy(x => x.Vehicle.RangeId)
.ThenBy(x => x.Rate.Rental)
.GroupBy(x => x.Vehicle.RangeId)
.Select(x => x.OrderBy(o => o.Rate.Rental).FirstOrDefault())
.OrderBy(x => x.Rate.Rental);
Run Code Online (Sandbox Code Playgroud)
任何帮助或指示将不胜感激。我无法弄清楚为什么原始查询没有使一切井然有序。
我希望它先按 RangeId 订购车辆,然后再按租金订购
在 LINQ to Entities 查询中,GroupBy
将简单地忽略a 之前的任何排序。您甚至不会在执行的 SQL 中看到它。那是因为实体框架将分组表达式按顺序排序(在您的情况下x => x.Vehicle.RangeId
)。这是为什么?
LINQ 的GroupBy
看起来和 SQL 很相似GROUP BY
,但实际上却大不相同。
GROUP BY
在 SQL 中是“破坏性的”,我的意思是除了列中的列之外的任何信息GROUP BY
都丢失了(聚合表达式除外)。如果你这样做...
SELECT Brand, COUNT(*)
FROM Cars
GROUP BY Brand
Run Code Online (Sandbox Code Playgroud)
...你只看到Brand
和他们的计数。您看不到组中的汽车。
这正是 LINQGroupBy
所做的:它生成一组完整的对象。原始数据中的所有信息都还在。您会看到按品牌分组的汽车。
这意味着翻译GroupBy
为的ORMGROUP BY
很难构建结果集。LINQ to SQL 就是这样做的。它首先执行一个GROUP BY
查询,然后它需要单独的查询(实际上每组一个)来弥补“丢失”的数据。
EF 的实现方式GroupBy
不同。它在一个查询中获取所有数据,然后在内存中构建组。您不会GROUP BY
在生成的 SQL 中看到。你会看到一个ORDER BY
。我认为 EF 更喜欢排序的 SQL 查询结果,以便在内存中进行更有效的处理。(我可以想象与管道中的其他 LINQ 语句更好地结合)。
这就是为什么之前的任何排序GroupBy
都被忽略的原因。以及为什么您只能在分组后应用排序。
表现绝对糟糕
从这里很难说为什么会这样。也许您可以在内存中进行排序:
var results = queryBuilder
.GroupBy(x => x.Vehicle.RangeId)
.Select(x => x.OrderBy(o => o.Rate.Rental).FirstOrDefault())
.Select(o => new { o.Rate.Rental, o }
.AsEnumerable()
.OrderBy(x => x.Rental);
Run Code Online (Sandbox Code Playgroud)
但这也可能是索引问题。如果 上没有合适的索引Rate.Rental
,则按该列排序的成本很高。
归档时间: |
|
查看次数: |
434 次 |
最近记录: |