итерация по DbSet vs IQueryable

используя Entity Framework я выбираю некоторые данные из таблицы и перебираю их с помощью foreach петли. Мне интересно, когда данные запрашиваются в следующих примерах?

Пример 1.

var countries = db.WorldCountries;
foreach(var item in countries)
{
    Console.WriteLine("Country: {0}", item.Country);
}

Пример 2.

var countries = db.WorldCountries.Where(t => t.Country == "Country Name");
foreach(var item in countries)
{
    Console.WriteLine("Country: {0}", item.Country);
}

в первом примере, countries is DbSet<WorldCountries> во втором примере, countries is IQueryable<out WorldCountries>.

без .ToList() в приведенных выше примерах, как полученные данные? Извлекается ли весь набор данных, когда the foreach начинается цикл (как будто .ToList() были вызваны в начале первой итерации) или запросы выдаются в базу данных на каждой итерации цикла.

спасибо.

1 ответов


в обоих примерах IQueryable<WorldCountries> компилируется в SQL и выполняется в точке ввода foreach (при foreach звонки GetEnumerator). Таким образом, вы получаете результат от БД непосредственно перед первой итерацией, а не по частям на каждой итерации.(Результаты поступают через DataReader, поэтому фактическая передача данных может выполняться по частям для каждой итерации, но я имею в виду, что на каждой итерации нет отдельного SQL-запроса).

отметим, что DbSet<T> осуществляет IQueryable<WorldCountries>, Так оба примера работают одинаково, за исключением того, что второй включает предложение where.

при добавлении .ToList, который выполняет итерацию и заполняет список перед возвратом, поэтому в этом случае вы передаете все необходимые данные из БД перед переходом к следующему оператору.