为什么实体框架在后面跟着不同时忽略顺序

本文关键字:顺序 实体 框架 在后面 为什么 | 更新日期: 2023-09-27 17:55:11

我想知道为什么下面的连接以无序方式返回值。是否明显意味着无法保证传递的IQueryable的顺序,因此 EF 不会费心在 SQL 中生成顺序依据子句。

 var currentUtc = DateTime.Now;
 var data = (from a in ItemsA
     join c in Customers on a.Fk_CustomerID equals c.ID into customerSubset
     from cs in customerSubset.DefaultIfEmpty()
     where cs.Age > 18)                                    
     orderby a.ID ascending
     select new
     {
       a.ID,
       a.someProperty,
       cs.CustomerUID,
       CustomerName = cs.Name,                               
       UpdateUTC = currentUtc
     }).Distinct().Take(1000).ToList();

奇怪的是,删除非重复项会在生成的 SQL 的内部查询中添加 order by 子句(您可以使用 Linqpad 查看生成的 SQL。

现在,如果我将最后一行替换为

.Distinct().OrderBy(x => s.ID).Take(1000).ToList();

我在 SQL 中获取 order by 子句,无论我在内部查询中是否有orderby a.ID ascending。这是有道理的,但是为什么在 orderby 之后链接不同也不会产生相同的顺序?

为什么实体框架在后面跟着不同时忽略顺序

SQL 中的 DISTINCT 操作不能保证顺序。在内部,它在确定行是否相同之前执行排序。

即使不能保证该顺序,因为查询引擎可以对数据进行分区以进行并行处理,然后重新组合分区数据以生成最终结果。

为了保证特定顺序,ORDER BY 子句或 OrderBy() 调用应该是 Skip()Take() 之前的最后一个