为啥 EF 6.4 生成的 SQL 出错了?

Posted

技术标签:

【中文标题】为啥 EF 6.4 生成的 SQL 出错了?【英文标题】:Why is the EF 6.4 generated SQL faulty?为什么 EF 6.4 生成的 SQL 出错了? 【发布时间】:2021-08-19 23:27:14 【问题描述】:

我有一个看起来像这样的查询。 UserId 是随机字母字符串。 searchCritera 是要搜索的模型。 searchCriteria.MainRoleValueList 包含要搜索的角色(枚举)

var criteria = DBContext.People.Include(w => w.Main).AsQueryable();

//A lot of code that doesnt affect this senario.

if (!string.IsNullOrEmpty(searchCriteria.UserIdLike))

     criteria = criteria.Where(i => i.UserId.Contains(searchCriteria.UserIdLike));

if (searchCriteria.MainRoleValueList != null && searchCriteria.MainRoleValueList.Count > 0)

         var MainMembership = DBContext.MainMemberships.Where(p => searchCriteria.MainRoleValueList.Contains(p.MainRoleValue) && p.ValidTo == null).Join(criteria,
                        main => new  main.UserId, main.Main_Id , current => new  current.UserId, current.Main_Id , (main, current) => main);

var tmp = MainMembership.ToList(); //Added line to trigger communication with SQL server

生成的sql代码是

SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[UserId] AS [UserId], 
    [Extent1].[Main_Id] AS [Main_Id], 
    [Extent1].[MainRoleValue] AS [MainRoleValue], 
    [Extent1].[ValidFrom] AS [ValidFrom], 
    [Extent1].[ValidTo] AS [ValidTo]
    FROM  [dbo].[MainRoleMembership] AS [Extent1]
    INNER JOIN [dbo].[Person] AS [Extent2] ON ([Extent1].[UserId] = [Extent2].[UserId]) AND ([Extent1].[Main_Id] = [Extent2].[Main_Id])
    WHERE ([Extent1].[MainRoleValue] IN (300, 400, 200, 410)) AND ([Extent1].[ValidTo] IS NULL) AND (([Extent2].[FullName] LIKE '%rty12tt%' ESCAPE N'~') 
    OR ([Extent2].[UserId] LIKE '%rty12tt%' ESCAPE N'~')) AND 
    ( EXISTS (SELECT 
        1 AS [C1]
        FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
        WHERE 1 = 0
    ))

除了最后一部分,它还有效

EXISTS (SELECT 
        1 AS [C1]
        FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
        WHERE 1 = 0

为什么要添加这个?因为它删除了我想要的正确结果。 如果我删除该部分并在 SQL 服务器上运行查询,我会得到我想要的用户。 我应该如何重写我的查询以便不包括在内?

添加:是的,有 UserId 的两个表没有外键 用户身份。这是系统中的一个糟糕设计,但我暂时无法修复。

添加:在表之间为 UserId 添加了一个外键,但没有帮助

【问题讨论】:

据我所知,这确实来自您认为的“大量代码不会影响此情景”。当 EF6 从模型约束 + 谓词推断谓词只能为假时,它总是这样做。 你在哪里对..有一个空列表,当它应该加入时添加 【参考方案1】:

我添加并与一个空列表进行比较..这就是为什么

EXISTS (SELECT 
        1 AS [C1]
        FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
        WHERE 1 = 0

已添加。为列表添加了计数检查,问题消失了

【讨论】:

以上是关于为啥 EF 6.4 生成的 SQL 出错了?的主要内容,如果未能解决你的问题,请参考以下文章

运行所选代码生成器时出错'无法检索'ERP.EF.StockItem'的元数据'找到不明确的匹配项

WCF / EF / SQL Server / VS2017 / C#:多层应用程序在部署到本地 IIS 10.0 作为托管服务器时出错

EF连接mysql出错

执行迁移 EF core 2.0 时出错,将身份 ID 从字符串更改为 int

为啥 EF Core 2.0 会生成多个重复的 SQL 语句?

在 Eclipse Luna 中配置 jboss-eap-6.4 服务器时分配正确的主目录时出错