EF core 6 选择空值,尽管 where 子句要求非空

2024-03-12

我有一个像这样的 Linq2Sql 查询:

Parent.Include(p => p.Children)
  .Where(p => p.Children.Any(c => c.SomeNullableDateTime == null)
    && p.Children
        .Where(c => c.SomeNullableDateTime == null)
        .OrderBy(c => c.SomeInteger)
        .First()
        .SomeOtherNullableDateTime != null
  )
  .Select(p => p.Children
        .Where(c => c.SomeNullableDateTime == null)
        .OrderBy(c => c.SomeInteger)
        .First()
        .SomeOtherNullableDateTime)
  .ToList();

在从 EF core 5 迁移到 EF core 6 之前,这种方法一直运行良好。对于 EF core 6,结果列表包含一些空值(不应出现这种情况,因为 where 条件要求非空值)。 EF core 6 中是否存在我不知道的重大更改/限制,或者这只是一个错误?

更新:这是输出的摘录

更新2:这是生成的SQL语句

SELECT(
    SELECT TOP(1)[p1].[SomeOtherNullableDateTime]
    FROM[Children] AS[p1]
    WHERE([p].[Id] = [p1].[ParentId]) AND[p1].[SomeNullableDateTime] IS NULL
    ORDER BY[p1].[SomeInteger])
FROM[Parent] AS[p]
WHERE EXISTS(
    SELECT 1
    FROM[Children] AS [c]
    WHERE ([p].[Id] = [c].[ParentId]) AND[c].[SomeNullableDateTime] IS NULL) AND EXISTS(
   SELECT 1
   FROM[Children] AS [c0]
    WHERE ([p].[Id] = [c0].[ParentId]) AND[c0].[SomeNullableDateTime] IS NULL)
GO

所以看来问题是其他一些可空日期时间(应该不为空)甚至不包含在生成的 SQL 的 where 子句中。

更新 3:这是 SQL EF core 5(正确)生成的

SELECT (
    SELECT TOP(1) [c].[SomeOtherNullableDateTime]
    FROM [Children] AS [c]
    WHERE ([p].[Id] = [c].[ParentId]) AND [c].[SomeNullableDateTime] IS NULL
    ORDER BY [c].[SomeInteger])
FROM [Parent] AS [p]
WHERE EXISTS (
    SELECT 1
    FROM [Children] AS [c0]
    WHERE ([p].[Id] = [c0].[ParentId]) AND [c0].[SomeNullableDateTime] IS NULL) AND (
    SELECT TOP(1) [c1].[SomeOtherNullableDateTime]
    FROM [Children] AS [c1]
    WHERE ([p].[Id] = [c1].[ParentId]) AND [c1].[SomeNullableDateTime] IS NULL
    ORDER BY [c1].[SomeInteger]) IS NOT NULL
GO

GitHub 上的开发团队已确认有两个不同的 bug 导致了这些问题:

https://github.com/dotnet/efcore/issues/26744 https://github.com/dotnet/efcore/issues/26744

https://github.com/dotnet/efcore/issues/26756 https://github.com/dotnet/efcore/issues/26756

不幸的是,他们表示这些错误不会在计划于 12 月发布的 6.0.1 版本中修复,但最早会在计划于 2022 年 2 月发布的另一个版本中修复。

由于这些错误会导致 EF core 6 悄悄地返回错误结果,并且许多用户很有可能搞乱他们的数据或根据错误数据做出决策(因为没有人会检查所有 Linq2SQL 查询是否生成正确的 SQL!?),我建议暂时不要使用 EF core 6!

这可能被视为基于意见,但请不要删除此答案,而是将其作为对其他开发人员的警告!

Update:现在这些问题已得到修复:

https://github.com/dotnet/efcore/pull/27284 https://github.com/dotnet/efcore/pull/27284

https://github.com/dotnet/efcore/pull/27292 https://github.com/dotnet/efcore/pull/27292

它们已被批准发布 6.0.3 版本,计划于 2022 年 3 月发布。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

EF core 6 选择空值,尽管 where 子句要求非空 的相关文章

随机推荐