我正在学习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());