DISTINCT() and ORDERBY issue



我正在学习LINQ to SQL,一切都很顺利,直到发生了一些奇怪的事情:

我试图做一个distinct的例子,所以,使用Northwind dabatase,我写了以下查询:

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

如果我为query中存储的查询打印LINQ到SQL生成的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,但CustomerID s没有排序!

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

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

正如我们所看到的**,ORDER BY子句丢失了。为什么?

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

来自Queryable。独特的文件;

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

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

你想要的可能更像这样,在完成Distinct()之后有一个OrderBy

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

尝试重新排列成员以将OrderBy放在Distinct之后。您必须恢复到方法链接:

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

最新更新