LINQ to Entities生成错误的SQL

Big*_*Dog 25 linq null entity-framework

我正在过滤IQueryable以返回将UserId(可空int)字段设置为null的所有实体.查询生成错误的SQL,因此失败 - 语句如下 -

var filtered = certificates.Where(c => !c.UserId.HasValue).Select(c => c.SubjectName);
Run Code Online (Sandbox Code Playgroud)

并生成的SQL是 -

SELECT 
CAST(NULL AS varchar(1)) AS [C1], 
CAST(NULL AS int) AS [C2], 
CAST(NULL AS datetime2) AS [C3], 
CAST(NULL AS datetime2) AS [C4], 
CAST(NULL AS bit) AS [C5], 
CAST(NULL AS datetime2) AS [C6], 
CAST(NULL AS int) AS [C7]
FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
WHERE 1 = 0
Run Code Online (Sandbox Code Playgroud)

任何想法WTF都在继续吗?这个想法很简单我只想返回字段UserId为false的所有行.UserId可以为空,被查询的表有三行与描述的条件匹配,但LINQ查询返回0.

谢谢!

Ger*_*old 33

这是EF在确定查询不会返回任何结果时生成的查询类型.这样的查询最小化了数据库处理.

EF如何确定?这只能是UserId在数据库中所知道的所有内容都不可为空的情况下.反过来,这只能是UserCertificate(POCO类)中根据需要映射的引用时.寻找类似的东西

HasRequired(t => t.User).WithMany(t => t.Certificates)
Run Code Online (Sandbox Code Playgroud)

在你的EntityTypeConfiguration<Certificate>,或OnModelCreating在你的DbContext.(在代码优先中,可以有一个必需的引用,而伴随的原始Id属性是可以为空的类型.在edmx文件中,这不会验证).

所以我认为User如果在数据库中外键可以为空,则必须映射为可选.

  • 这是绝对正确的。我们只是遇到了同样的问题。db列已转换为可为空,但更改未传播到edm。有趣的是,我们仅通过在[[SingleRowTable1]]上进行搜索而找到了该帖子,因为我们在Profiler中看到了该查询,并且具有相同的_WTF_反应! (2认同)

sca*_*tag 2

也许你可以尝试更明确的选项

  var filtered = certificates.Where(c => c.UserId == null).Select(c => c.SubjectName);
Run Code Online (Sandbox Code Playgroud)