为什么实体框架在跟着“不重复”时会忽略顺序?

arv*_*man 2 c# sql-server entity-framework

我想知道为什么以下联接以无序方式返回值。确实表明IQueryable不能保证传递的顺序,因此EF不会麻烦在SQL中生成order by子句。

 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();
Run Code Online (Sandbox Code Playgroud)

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

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

.Distinct().OrderBy(x => s.ID).Take(1000).ToList();
Run Code Online (Sandbox Code Playgroud)

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

Pan*_*vos 6

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

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

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