【发布时间】:2018-01-10 12:04:21
【问题描述】:
我正在将软件从 EF 6 迁移到 EF Core。在测试过程中,我注意到 Linq 的解释方式有所不同。
我的 Linq
app.Deputies
.Include(d => d.User)
.Where(d => d.User == null)
.ToList()
在 EF 6 中,它会产生这样的查询(为阅读目的而简化)
SELECT
d.*
FROM Deputy d
LEFT JOIN User u ON u.Id = d.UserId
WHERE u.Id IS NULL
在 EF Core 中,SQL 看起来像这样
SELECT
d.*
FROM Deputy d
LEFT JOIN User u ON u.Id = d.UserId
WHERE d.UserId IS NULL
即使我这样做 .Where(d => d.User.Id == null) 也不会更改生成的查询。
EF 6 的配置如下所示:
.HasOptional(d => d.User).WithMany().HasForeignKey(d => d.UserId);
EF Core 的配置如下所示:
.HasOne(d => d.User).WithMany().HasForeignKey(d => d.UserId);
我是否错过了配置中的某些内容或任何想法以及如何实现与 EF 6 中相同的 SQL?
(我使用的是 SQL Server)
编辑:数据库上的代理和用户之间没有 FK。 (仅在模型中)
【问题讨论】:
-
您发布的 2 个 SQL 查询是一回事。
-
只是想知道,为什么要包括检查 null 而不是直接检查外键?即
app.Deputies.Where(d => d.UserId == null).ToList() -
核心版本更好,因为它不需要在查询计划中加入,那你为什么要EF6版本?
-
我以为你有。重要的区别是核心查询过滤
Deputy而不是User。这使得查询计划的效率大大提高。 -
好的,我错过了那个。在这种情况下,EF 存储模型和实际存储模型之间存在语义差异,您有责任解决它,例如将其更改为
Any查询(而不是Users.Any(u.Id == d.UserId))。
标签: c# sql sql-server entity-framework entity-framework-core