DISTINCT()和ORDERBY问题
我正在学习LINQ-to-SQL,一切都很顺利,直到发生奇怪的事情:
我试着做一个distinct
的例子,所以,使用Northwind dabatase我写了以下查询:
var query = from o in db.Orders orderby o.CustomerID select new { o.CustomerID };
如果我打印LINQ-to-SQL为查询中存储的query
生成的SQL,它看起来像这样:
SELECT [t0].[CustomerID] FROM [dbo].[Orders] AS [t0] ORDER BY [t0].[CustomerID]
因此,像往常一样,查询会按字母顺序排列Orders
表中每个Order
所有CustomerID
。
但! 如果我像这样使用Distinct()
方法:
var query = ( from o in db.Orders orderby o.CustomerID select new { o.CustomerID }).Distinct();
该查询带来了Distinct
子句的预期结果,但是尽管我通过orderby o.CustomerID
编写了orderby o.CustomerID
,但是没有订购CustomerID
!
第二个LINQ查询的SQL查询如下:
SELECT DISTINCT [t0].[CustomerID] FROM [dbo].[Orders] AS [t0]
我们可以看到**缺少ORDER BY
子句。 这是为什么?
当我使用Distinct()
方法时,为什么ORDER BY
子句会消失?
来自Queryable.Distinct文档 ;
预期的行为是它返回源中唯一项的无序序列。
换句话说,当您对其使用Distinct()
时,现有IQueryable的任何顺序都会丢失。
你想要的可能更像是这样,在Distinct()完成之后的OrderBy();
var query = (from o in db.Orders select new { o.CustomerID }).Distinct().OrderBy(x => x.CustomerID);
尝试重新排列成员以在Distinct之后放置OrderBy。 你将不得不恢复方法链:
db.Orders.Select(o=>o.CustomerId).Distinct().OrderBy(id=>id);
这将是在Enumerable Linq中设置查询的更有效方式,因为OrderBy将仅对唯一项而不是对所有项进行操作。 另外,根据MSDN ,Enumerable.Distinct无论如何都不保证元素的返回顺序,因此在重复删除之前的排序是没有意义的。
由于使用了distinct,因此无法保证返回列表的顺序。 LinqToSql很聪明,可以识别它,因此它忽略了它。
如果您在您的Distinct之后下订单,一切都会按照您的意愿发生。
var query = (from o in db.Orders select new { o.CustomerID }).Distinct().OrderBy(o => o.CustomerID);
要么
var query = db.Orders.Select(o => o.CustomerID).Distinct().OrderBy(o => o.CustomerID);
请参阅此文章以获得澄清:
你可以用这个结构来模拟ORDERBY和DISTINCT:
var distinctItems = employees.GroupBy(x => x.EmpID).OrderBy(x => x).Select(y => y.First());