C# Linq 排序和取值

7

我正在使用C#语言的linq进行查询。

在选择并保存查询后,我必须对其进行排序并取出15行...

var query = from a 
[...]
select new
{
    a.id,
    a.desc,
}
[...]

有没有任何不同之处在于这样做:
return query.OrderByDescending(o => o.id).Take(15);

还有这个吗?

return query.Take(15).OrderByDescending(o => o.id);

非常感谢你!

4
是的。第一个会先排序,然后获取前15个结果,而第二个会先获取前15个结果,然后对它们进行排序。 - Reinstate Monica Cellio
2
第一个返回按ID排序的前15个记录。第二个返回无法预测的顺序的记录,取其中的15个,并按ID对这些任意行进行排序。 - Tim Schmelter
4个回答

12
是的,非常正确。这是一种操作顺序的问题。
假设您有一个数据集:
A
F
B
D
F
C

如果你执行return query.Take(3).OrderBy(o => o.name);,你将得到

A
B
F

但是,如果您执行 return query.OrderBy(o => o.name).Take(3);,那么您将会得到:

A
B
C

2
是的。一个人拿15个并进行订购,另一个人订购它们并拿走了15个。
using System.Linq;

public static void Main(string[] args)
{
    var nums = Enumerable
        .Range(0, 50)
        .OrderBy(o => Guid.NewGuid().GetHashCode())  // poor mans shuffle
        .ToList(); 

    Console.WriteLine(string.Join(",", nums));

    Console.WriteLine(string.Join(",", nums.Take(15).OrderBy(i => i)));

    Console.WriteLine(string.Join(",", nums.OrderBy(i => i).Take(15)));

    Console.ReadLine();
}

输出:

6,32,22,18,9,11,5,33,0,24,1,42,38,30,21,20,23,2,36,8,15,12,29,47,46,19,49,44,4,3
    7,40,3,10,41,34,17,31,16,43,35,39,25,27,45,7,28,14,13,26,48

0,1,5,6,9,11,18,21,22,24,30,32,33,38,42 // nums.Take(15).OrderBy(i => i)

0,1,2,3,4,5,6,7,8,9,10,11,12,13,14      // nums.OrderBy(i => i).Take(15)

测试相对简单...


2
两个查询的区别在于第一个查询将按照id降序排列列表中的前15项,而第二个查询将按照“自然”顺序获取前15项,然后按照id降序重新排序并返回给您。
由于RDBMS中的“自然”顺序不能保证在多个请求之间保持不变,因此只有第一个查询将返回一致的结果。实际上,每次调用第二个查询时,它都可能返回完全不同的记录集。
如果在内存中执行这两个查询,则结果将是一致的。
可以通过一个简单的例子来很容易地说明两种查询的区别:包含100个记录和ID为1到100(包括)的记录,按其ID升序排列。第一个查询将返回ID为100、99、98、...、86的记录,而第二个查询将返回ID为15、14、13、...、1的记录。

1

是的,这两个查询将返回不同的结果,因为:

  • query.OrderByDescending(o => o.id).Take(15)会对整个源查询进行排序,然后返回前15个项目。这将导致您在使用的整个排序数据集中获得前15个项目。
  • query.Take(15).OrderByDescending(o => o.id)将获取查询中的前15个项目(按它们当前的顺序),并对这些前15个项目进行排序(所以这可能是您想要的)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接