对于我编写的每个LINQ查询,我总是使用foreach循环来完成结果。现在,我有一个程序,我想获得结果的前50行,用这些行做一些计算,然后获得结果的下50行等。
使用LINQ和C#执行此操作的好标准方法是什么?
答案 0 :(得分:5)
.Skip()。在这种情况下,Take()将是最好的方法(就清晰度而言)。例如:
var results = db.Table.Select(); // Your query here
int rowCount = results.Count(); // Count rows once and store
for(int i = 0; i <= rowCount; i += 50)
{
var paged = results.Skip(i).Take(50);
// do the calculations with the groups of 50 here
}
值得注意的是,即使这看起来更清楚(你从结果中取50个小组),每次你调用Skip()和Take()时,都有可能再次枚举该集合。 ...实际上效率低于仅使用foreach
一次枚举结果的效率。
答案 1 :(得分:4)
您可以通过ie使用组:
data.Select((item, index) => new {item, index}).GroupBy(g => g.index / 50)
然后你就会对每个小组进行操作。
答案 2 :(得分:2)
在不了解数据性质和/或计算的情况下,执行此操作的“良好标准”方法可能是foreach
循环!
如果您可以提供有关数据性质和要执行的计算的一些信息,将会有所帮助。根据这一点,最佳答案可能是foreach
,Skip
/ Take
,GroupBy
或者其他可能完全相同的内容。
答案 3 :(得分:0)
使用.Skip(...).Take(...)
将适用于分页。但需要考虑的是,IEnumerable<...>
这将在每次处理时重新计算可枚举数。这是消耗的东西,而不是可重置,你可能会有问题。此方法集可以解决此问题。
public static class EnumerableEx
{
public static IEnumerable<IEnumerable<T>> AsPages<T>(
this IEnumerable<T> set, int pageLength)
{
using (var e = set.GetEnumerator())
while (true)
yield return GetPage(e, pageLength);
}
private static IEnumerable<T> GetPage<T>(
IEnumerator<T> set, int pageLength)
{
for (var position = 0;
position < pageLength && set.MoveNext();
position++)
yield return set.Current;
}
}
...以下是一个重要原因的用法示例。
class Program
{
private static int _last = 0;
private static IEnumerable<int> GetValues()
{
while (true)
yield return _last++;
}
static void Main(string[] args)
{
for (var i = 0; i < 3; i++)
foreach (var value in GetValues().Skip(5 * i).Take(5))
Console.Write(value + ",");
// 0,1,2,3,4,10,11,12,13,14,25,26,27,28,29,
Console.WriteLine();
_last = 0;
foreach (var page in GetValues().AsPages(5).Take(3))
foreach (var value in page)
Console.Write(value + ",");
// 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
}
}
答案 4 :(得分:-3)
有效的事情
var page = (From c In db.Customers Order By c.ContactName, c.City Descending
Select c).Skip(50).Take(50)