在没有Foreach循环的LINQ结果中访问行?

时间:2010-07-09 15:33:29

标签: c# linq

对于我编写的每个LINQ查询,我总是使用foreach循环来完成结果。现在,我有一个程序,我想获得结果的前50行,用这些行做一些计算,然后获得结果的下50行等。

使用LINQ和C#执行此操作的好标准方法是什么?

5 个答案:

答案 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)

然后你就会对每个小组进行操作。

与此类似:How to use Linq to group every N number of rows

答案 2 :(得分:2)

在不了解数据性质和/或计算的情况下,执行此操作的“良好标准”方法可能是foreach循环!

如果您可以提供有关数据性质和要执行的计算的一些信息,将会有所帮助。根据这一点,最佳答案可能是foreachSkip / TakeGroupBy或者其他可能完全相同的内容。

答案 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)