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); 

请参阅此文章以获得澄清:

http://programminglinq.com/blogs/marcorusso/archive/2008/07/20/use-of-distinct-and-orderby-in-linq.aspx

你可以用这个结构来模拟ORDERBY和DISTINCT:

 var distinctItems = employees.GroupBy(x => x.EmpID).OrderBy(x => x).Select(y => y.First());