[英]Better understanding of Entity Framework Core querying and DbSet impact
我是 Entity Framework 的新手,想对某些事情进行一些澄清。 我了解DbContext
,例如指向带有连接字符串的 SQL 数据库。 在DbContext
中,您声明您希望/计划从所述 SQL 数据库公开和获取数据的DbSet<perEachTable>
。
现在,您进入 LINQ,我了解了一些链接,例如可枚举的事物列表和寻找某些符合条件的 where 条件条目。
现在,我更大的问题以及 EF 如何查询。 您有一个指向 SQL Server 的DbContext
。 它有一张有 25 万客户的桌子。 它的主键定义为预期的Id
(或CustomerId
)。 您想根据用户的电子邮件地址查询和查找客户(预期查询的常见类型)。 客户表在电子邮件上有一个索引。
在我看到的 LINQ 查询中,它指的是任何表的DbSet
并运行 where 子句,例如
using (var context = new DBCustomers())
{
var query = context.Customer
.Where(c => c.EMail == "someEMail@whereEver.com")
.FirstOrDefault<Customer>();
}
我的想法是整个客户列表都被从它的 DbSet 上下文中拉下来了。 然后它运行链接WHERE
子句来查找电子邮件。 我不认为我想每次都减少 250k 客户只是为了 LINQ 迭代他们。
为什么WHERE
实际上并没有使用整个客户数据集(尤其是当它继续增长时),只是根据可用的索引进行优化,实际上并没有把所有东西都拉下来。
这是否只是一个正在应用的魔法黑盒,EF 只是将符合条件的最终条目交给您(或者如果其他更开放的查询则很少)。
我还看到了使用完全编写的 SQL 语句和参数化的 EF Core 实例,这是我更习惯做的事情。 让 SQL Server 引擎根据与合格索引最匹配的显式条件返回数据。
感谢对基础操作的澄清。
我不是 EF 方面的专家,但不要求整张桌子。
它不返回IEnumerable
而是返回IQueryable
,它将基于 linq 语句生成 SQL 查询,并在迭代时在 sql-server 上执行它(例如 foreach 循环)。
您可以使用以下方法获取 SQL 查询:
var query = context.Customer.Where(x => x.Id == 1);
Console.WriteLine(query.ToQueryString());
您的代码DbSet<T>.Where()
正在调用Queryable.Where()
扩展方法,而不是Enumerable.Where()
。
Enumerable.Where
返回一个枚举,它将逐步遍历基础枚举,对每个项目应用过滤器。
Queryable.Where()
的目的非常不同。 它返回一个IQueryable
,它捕获了您正在做什么的描述。 每种方法都可以帮助您构建一个Expression Tree ,它就像一个仅被部分编译的 lambda 函数。
IQueryable
还实现IEnumerable
。 当您开始尝试枚举结果时,表达式树将被“编译”。 因为您从DbSet
创建了IQueryable
,所以 EF Core 将接管此编译过程。 试图创建一个高效的 sql 语句和一个将结果转换为对象的函数。
为了效率,这个函数和sql都会被缓存。 每次尝试编译相同的表达式时,都会跳过大部分编译过程。
EF 将从您的query
对象构造一个 SQL 查询并在服务器上执行该查询。 这样只返回 SQL 查询的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.