解释每个操作的位置,即 WHERE 和 TAKE。 在内存中或在数据库端对于 IEnumerable 和 IQueryable。
IEnumerable<Student> listStudents = DBContext.Students.Where(x => x.Gender == "Male");
listStudents = listStudents.Take(2);
foreach (var std in listStudents)
{
Console.WriteLine(std.FirstName + " " + std.LastName);
}
IQueryable<Student> listStudents = DBContext.Students
.AsQueryable()
.Where(x => x.Gender == "Male");
listStudents = listStudents.Take(2);
foreach (var std in listStudents)
{
Console.WriteLine(std.FirstName + " " + std.LastName);
}
假设
DBContext.Students
是 DbSet<Student>
,那么对于第一个片段,EF 应该将 Where
转换为 SQL,但当/如果实现实现时,Take
将在客户端执行。第二个片段应将 Where
和 Take
翻译为适当的 SQL。请注意,实际差异不会那么大 - 两个查询都不应该获取额外的数据(因为只有 Take
是“不同的”)。但如果您将第一个片段重写为:
IEnumerable<Student> listStudents = DBContext.Students;
listStudents = listStudents
.Where(x => x.Gender == "Male")
.Take(2);
然后可能会导致向客户端获取额外的数据。
所有这些都可以通过启用 logging 轻松地使用 EF Core 进行测试(另请注意自第 5 版本以来可用的
EntityFrameworkQueryableExtensions.ToQueryString(IQueryable)
)。