繁体   English   中英

更好地理解 Entity Framework Core 查询和 DbSet 影响

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM