DISTINCT()和ORDERBY问题

时间:2012-09-14 17:05:01

标签: c# .net linq linq-to-sql

我正在学习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]

因此,通常情况下,查询会按字母顺序排列CustomerID表中每个Order的所有Orders

但是!如果我使用这样的Distinct()方法:

var query = (
    from o in db.Orders
    orderby o.CustomerID
    select new
    {
        o.CustomerID
    }).Distinct();

查询带来了Distinct子句的预期结果,但尽管我写了CustomerID,但orderby o.CustomerID没有被排序!

第二个LINQ查询的SQL查询如下:

SELECT DISTINCT [t0].[CustomerID]
FROM [dbo].[Orders] AS [t0]

我们可以看到** ORDER BY子句丢失了。那是为什么?

当我使用ORDER BY方法时,为什么Distinct()子句会消失?

4 个答案:

答案 0 :(得分:35)

来自Queryable.Distinct documentation;

  

预期的行为是它返回源中唯一项目的无序序列。

换句话说,当您在其上使用Distinct()时,现有IQueryable的任何订单都会丢失。

你想要的可能是更像这样的东西,在完成Distinct()之后的OrderBy();

var query = (from o in db.Orders
             select new
             {
                 o.CustomerID
             }).Distinct().OrderBy(x => x.CustomerID);

答案 1 :(得分:13)

尝试重新排列成员以在Distinct之后放置OrderBy。你将不得不恢复方法链:

db.Orders.Select(o=>o.CustomerId).Distinct().OrderBy(id=>id);

无论如何,这将是在Enumerable Linq中设置查询的更有效方法,因为OrderBy将仅对唯一项而不是所有项进行操作。另外,根据MSDN,Enumerable.Distinct无论如何都不保证元素的返回顺序,因此在重复删除之前的排序是没有意义的。

答案 2 :(得分:3)

由于使用了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

答案 3 :(得分:1)

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

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