IQueryable <T>метод расширения для получения данных в пакетном режиме - PullRequest
6 голосов
/ 09 ноября 2011

Кто-нибудь нашел / закодировал метод расширения, который запрашивает данные (используя linq to sql ) в пакетах? Я видел расширения IEnumerable, но я ищу что-то, что я мог бы использовать так:

IQueryable<Order> orders = from i in db.Orders select i;
foreach(var batch in orders.InBatches(100))
{
   //batch of 100 products
   foreach(var order in batch)
   {
      //do something
   }
}

Ответы [ 4 ]

10 голосов
/ 09 ноября 2011

Что вы можете сделать, это:

public static IEnumerable<IQueryable<T>> InBatches(
    this IQueryable<T> collection, int size)
{  
    int totalSize = collection.Count();

    for (int start = 0; start < totalSize; start += size)
    {
        yield return collection.Skip(start).Take(size);
    }
}

Этот метод расширения позволяет вам делать дополнительные фильтры по возвращаемым IQueryables. Однако полезность довольно ограничена. Я не могу придумать ни одного хорошего сценария для этого :-). В большинстве сценариев вы просто хотите транслировать результаты, и возвращение IEnumerable<IEnumerable<T>> будет работать нормально, и даже лучше, поскольку это приведет к одному SQL-запросу, а показанный подход приведет к N + 1 запросам.

3 голосов
/ 09 ноября 2011

Что не так с Take и Skip?Это операторы LINQ для получения пакетов из IEnumerable<T> или IQueryable<T> (и их неуниверсальных аналогов).

1 голос
/ 16 августа 2012

Если вам не нужны сами пакеты, и вы просто хотите разорвать соединения для размера или транзакции, вы можете сделать следующее:

public static IEnumerable<T> InBatches<T>(this IQueryable<T> collection, int batchSize)
{
    int start = 0;
    int records = 0;
    IQueryable<T> batch;

    // For the first batch
    start -= batchSize;

    do {
        records = 0;
        start += batchSize;
        batch = collection.Skip(start).Take(batchSize);

        foreach (T item in batch) {

            records += 1;
            yield return item;
        }

    } while (records == batchSize);
}
0 голосов
/ 07 февраля 2017

MoreLINQ, которая является фантастической библиотекой, поставляется с методом Batch, который делает именно это.

https://github.com/morelinq/MoreLINQ

Batch

Пакетирует исходную последовательность в размерныйведра.

Этот метод имеет 2 перегрузки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...