Медленный foreach () в запросе LINQ - ToList () значительно повышает производительность - почему это так?

Я как бы понимаю всю концепцию отложенного выполнения, но следующее меня озадачило ...

В DataTable, содержащем около 1000 строк, я вызываю AsEnumerable () . Затем я выбираю объекты, возвращенные в IEnumerable строго типизированных классов (1) ... Вот где я запутался: я выполняю цикл foreach для коллекции; выбор материала из отдельных элементов в коллекции с помощью набора Where () вызовов (2) ... И это очень медленно.

  1. DataTable.AsEnumerable (). Select (r => new ObjectRepresentation {...});
  2. item.Where (i => i.SomeEnum == SomeEnum.Something)


... Но если Я вызываю ToList () сразу после моего вызова AsEnumerable () в DataTable, цикл foreach выполняется менее секунды.

Что мне здесь не хватает? Действительно ли я вызываю AsEnumerable () каждый раз, когда мой цикл повторяется? Или каждый раз, когда я обращаюсь к элементу коллекции? Или каждый раз, когда я вызываю Where () для элемента в коллекции? Или все вышеперечисленное?


Обновление

Примерно полный код:

public class ObjectRepresentation
{
    public SomeEnum SomeEnum { get; set; }
}


var collection = DataTable.AsEnumerable().Select(r => new ObjectRepresentation
{
    SomeEnum = (SomeEnum)Convert.ToInt32(r["SomeEnum"])
});

foreach(var item in collection) // slow loop
{
    // 10 or so Where() calls on item inside this loop
}

collection = collection.ToList(); // Hit hyper speed button!

foreach(var item in collection) // fast loop
{
    // 10 or so Where() calls on item inside this loop
}
12
задан cllpse 27 August 2010 в 08:05
поделиться

2 ответа

Он не получит все элементы из базы данных, пока вы не наберете

 ToList or First or Single

Foreach, вы отправляете запрос в базу данных для каждого элемента. Так он работает медленнее. Откройте профилировщик sql, чтобы лучше понять.

9
ответ дан 2 December 2019 в 07:20
поделиться

Вы не понимаете, какие методы откладываются, а какие нет, поэтому вы не понимаете, когда ваш код определяет операции, а когда выполняет операции.

Все они отложены. Они определяют, но не выполняют операцию.

source.AsEnumerable
source.Select
source.Where

Они перечисляют источник и поэтому не откладываются.

source.ToList
source.First
source.Single
foreach(var x in source)
12
ответ дан 2 December 2019 в 07:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: