迭代DbSet <TEntity> vs IQueryable <out T>

nom*_*mad 7 entity-framework

使用实体框架我从表中选择一些数据并使用循环迭代它foreach.我想知道以下示例中何时查询数据?

例1.

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

例2.

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

在第一个例子中,countriesDbSet<WorldCountries>在第二个例子中,countriesIQueryable<out WorldCountries>.

如果没有.ToList()上面的示例,如何检索数据?是否在foreach循环开始时检索整个数据集(就像.ToList()在第一次迭代开始时调用的那样),或者在循环的每次迭代中向数据库发出查询.

谢谢.

Ere*_*mez 10

在这两个示例中,IQueryable<WorldCountries>都编译为SQL并在您输入的位置foreach(foreach调用时GetEnumerator)执行.所以你在第一次迭代之前就收到了db的结果,而不是每次迭代都是一块一块的.(结果是通过DataReader得到的,所以实际的数据传输可能是每次迭代都是一块一块地完成但是我的意思是,那里在每次迭代时不是单独的SQL查询).

注意,DbSet<T>也实现了IQueryable<WorldCountries>,所以你的两个例子都是一样的,除了第二个例子碰巧包含一个where子句.

当您添加时.ToList,它会在返回之前迭代并填充列表,因此在这种情况下,您将转移数据库中的所有必要数据,然后再转到下一个语句.

  • 我能够确认你是正确的,它确实分批提取数据,而不是一次全部.我通过迭代一个大的dbset编写了一个测试 - 通过我杀死该数据库连接的部分方式,并且正如预期的那样抛出了一个错误. (6认同)