Linq-to-sql orderby thenby
Linq-to-sql orderby thenby问题的出现原因是在使用Linq查询时,希望按照多个字段进行排序,但不想使用扩展语法。而解决方法是使用逗号将字段分隔开来进行排序。
当在Linq查询中连续使用orderby关键字时,元素在概念上首先按照第一个orderby进行排序,然后再按照第二个orderby进行排序。由于排序被定义为稳定排序(与第二个orderby相连的对象将保持与第一个orderby排序后的相同顺序),这实际上意味着以下代码:
var query = from x in l orderby x.A orderby x.B select x;
等效于:
var query = from x in l orderby x.B, x.A select x;
这导致了orderby的顺序与预期的相反。
可以通过在LINQ to SQL中进行测试来验证这一点。创建了以下查询:
var query = from a in dc.Orders orderby a.Date orderby a.CustomerID select a;
生成的SQL如下:
SELECT [t0].[ID], [t0].[CustomerID], [t0].[Date], [t0].[Description] FROM [dbo].[Order] AS [t0] ORDER BY [t0].[CustomerID], [t0].[Date]
注意,orderby a.Date并没有被忽略。两个orderby的条件都包含在ORDER BY子句中,但顺序与预期相反。
根据规范,OrderBy始终是稳定排序(无论LINQ提供程序如何)。这意味着“如果两个元素的键相等,则元素的顺序将保持不变”。链式OrderBy是否保留排序取决于所使用的键,而不是LINQ提供程序(尽管这显然会影响键值)。
经过更多的研究,我认为你是对的。奇怪的是,你在引用MSDN的答案中提到的“Doing this introduces a new primary ordering that ignores the previously established ordering.”与你在评论中所说的相矛盾。但我认为是MSDN错了。
它并不直接相矛盾,只是有些混淆。它的意思是新的主排序不会考虑先前建立的排序。然而,一旦应用了初始排序,如果新的排序发现键值相等,则不会重新排序这些项。因此,实际上两个陈述都是正确的,只是不够清楚。
我现在明白了。我同意你的观点,这确实令人困惑。:)我已经在LINQ to Objects和LINQ to SQL中进行了测试,排序在两种情况下都是稳定的。我必须说我有点惊讶的是SQL恰好是应该的-一个带有反转条件的单个ORDER BY。某人在这方面做得很好!
Linq to SQL是一个用于在.NET应用程序中查询和操作数据库的技术。在进行查询时,我们可能需要对结果进行排序。在Linq to SQL中,我们可以使用orderby关键字对结果进行排序,并且还可以使用thenby关键字对排序结果进行二次排序。
在使用查询表达式语法时,使用thenby非常简单,只需要在初始orderby语句后加上逗号和第二个排序条件即可。例如:
Liststudents = GetStudents(); IEnumerable sortedStudents = from student in students orderby student.Last ascending, student.First ascending select student;
然而,在使用标准查询操作符(扩展方法)时,对结果进行第二次排序实际上会将第二个orderby应用于包含第一个orderby的查询结果。实际上,只有第二个orderby会起作用,尽管计算第一个orderby仍然需要花费CPU时间。
这个问题在MSDN文档的Enumerable.OrderBy和Enumerable.ThenBy方法的说明中有明确的解答:
因为IOrderedEnumerable继承自IEnumerable,所以可以在调用OrderBy、OrderByDescending、ThenBy或ThenByDescending方法的结果上调用OrderBy或OrderByDescending。这样做会引入一个新的主排序,忽略先前建立的排序。
因此,为了在Linq to SQL中使用orderby和thenby进行多次排序,我们需要使用查询表达式语法,而不是标准查询操作符。这样可以确保多个排序条件都会被正确地应用。
Linq提供了一种方便的方法来对序列进行排序,通过使用OrderBy
方法可以对序列进行升序排序。然而,在某些情况下,我们可能需要对序列进行多级排序。这时就可以使用ThenBy
方法来应用第二个升序排序。
与T-SQL中的多级排序类似,我们可以使用ThenBy
方法来实现。例如,在T-SQL中,我们可以这样写查询语句:Select * from Customer order by FirstName,lastName
。在Linq中,我们可以这样写:
var thenby = mode.CustList.Select(cus => new { cus. FirstName, cus. LastName, cus. EmailAddress }).OrderBy(cus => cus. FirstName).ThenBy(cus => cus. LastName);
上述代码中,OrderBy
方法对序列按照FirstName进行升序排序,然后使用ThenBy
方法对排序后的序列按照LastName进行升序排序。
这个问题的出现是因为在某些情况下,我们需要对序列进行多级排序,但是Linq中的OrderBy
方法只能实现单级排序。为了解决这个问题,Linq提供了ThenBy
方法,它可以在OrderBy
方法之后使用,用于应用第二个升序排序。
通过使用ThenBy
方法,我们可以轻松地对序列进行多级排序,实现更精确的排序需求。在上述代码中,我们先按照FirstName进行升序排序,然后再按照LastName进行升序排序。
,Linq中的ThenBy
方法解决了需要对序列进行多级排序的问题。它可以在OrderBy
方法之后使用,用于应用第二个升序排序。通过使用ThenBy
方法,我们可以轻松地实现多级排序需求。