我正在学习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()
子句会消失?
答案 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);
请参阅此文章以获得澄清:
答案 3 :(得分:1)
你可以用这个结构来模拟ORDERBY和DISTINCT:
var distinctItems = employees.GroupBy(x => x.EmpID).OrderBy(x => x).Select(y => y.First());