asp.net - LINQ 实体Where 子句位置不正确

标签 asp.net sql-server entity-framework linq linq-to-entities

显然我遗漏了 LINQ toEntity 的工作原理。希望大家能够指导我。

请在本地尝试以下操作,如果您看到相同的结果,请告诉我。这里真的很奇怪......

让我们看一下使用导航属性的非常简单的 LINQ 表达式。

这是在 LinqPad 中的 C# 语句中生成的。

var result = (from ge in group_execution
                where ge.automation_sequences.project.client_id == 1 && ge.parent_group_exec_id != null
                select new
                {
                    ge.id,
                    ge.parent_group_exec_id,
                    ge.automation_sequences.project.client_id
                });
result.Dump();

或者,我们可以使用联接...这将导致相同的不良结果,但让我们继续...

var result = (from ge in group_execution
            join aseq in automation_sequences on ge.automation_sequence_id equals aseq.id
            join p in project on aseq.project_id equals p.id
            where p.client_id == 1 && ge.parent_group_exec_id != null
            select new
            {
                ge.id,
                ge.parent_group_exec_id,
                p.client_id
            });
result.Dump();

这些非常简单的 LINQ 表达式生成以下 SQL:

SELECT 
    [Filter1].[id1] AS [id], 
    [Filter1].[parent_group_exec_id] AS [parent_group_exec_id], 
    [Extent5].[client_id] AS [client_id]
    FROM    (SELECT [Extent1].[id] AS [id1], [Extent1].[automation_sequence_id] AS [automation_sequence_id], [Extent1].[parent_group_exec_id] AS [parent_group_exec_id]
        FROM   [dbo].[group_execution] AS [Extent1]
        INNER JOIN [dbo].[automation_sequences] AS [Extent2] ON [Extent1].[automation_sequence_id] = [Extent2].[id]
        INNER JOIN [dbo].[project] AS [Extent3] ON [Extent2].[project_id] = [Extent3].[id]
        WHERE ([Extent1].[parent_group_exec_id] IS NOT NULL) AND (1 = [Extent3].[client_id]) ) AS [Filter1]
    LEFT OUTER JOIN [dbo].[automation_sequences] AS [Extent4] ON [Filter1].[automation_sequence_id] = [Extent4].[id]
    LEFT OUTER JOIN [dbo].[project] AS [Extent5] ON [Extent4].[project_id] = [Extent5].[id]

这让我很困惑。我一生都无法理解为什么 LINQ 会这样做。太可怕了,看看执行计划就知道了:

enter image description here

现在让我们在 SSMS 中手动清理它并查看正确的 SQL 和执行计划:

enter image description here

好多了,但是我们如何让 LINQ 这样做呢?

还有人看到这个吗?有其他人见过这个并纠正它吗?如果是的话,如何纠正?

感谢您对此问题的调查。

<小时/>

更新,尝试 Chris Schaller 修复:

var result = (from ge in group_execution
                select new
                {
                    ge.id,
                    ge.parent_group_exec_id,
                    ge.automation_sequences.project.client_id
                }).Where(x=>x.client_id == 1 && x.parent_group_exec_id != null);
result.Dump();

让大家知道我正在通过 SQL Server Profiler 监视 SQL。如果有人知道这样做有任何问题,请告诉我。

enter image description here

<小时/>

更新,修复了 JOINS,但不是导航属性,还有一个原因,但为什么?

这是您的解决方案:

var result = (from ge in group_execution.Where(x=>x.parent_group_exec_id != null)
            join aseq in automation_sequences on ge.automation_sequence_id equals aseq.id
            join p in project on aseq.project_id equals p.id
            where p.client_id == 1// && ge.parent_group_exec_id != null
            select new
            {
                ge.id,
                ge.parent_group_exec_id,
                p.client_id
            });
result.Dump();

enter image description here

空检查不应该导致框架像这样困惑。为什么我一定要这样写呢?对我来说,这似乎是框架中的一个缺陷。这会让我的动态表达式写起来有点困难,但也许我可以找到一种方法。

导航属性仍然​​困惑......所以我仍然很难过。下图:

var result = (from ge in group_execution.Where(x=>x.parent_group_exec_id != null)
                where ge.automation_sequences.project.client_id == 1// && ge.parent_group_exec_id != null
                select new
                {
                    ge.id,
                    ge.parent_group_exec_id,
                    ge.automation_sequences.project.client_id
                });
result.Dump();

enter image description here

最佳答案

将 where 子句移至定义了 select 语句的结构之后

var result = (from ge in group_execution
            select new
            {
                ge.id,
                ge.parent_group_exec_id,
                ge.automation_sequences.project.client_id
            }).Where(x => x.client_id == 1 && x.parent_group_exec_id != null)
result.Dump();

关于asp.net - LINQ 实体Where 子句位置不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48586088/

相关文章:

sql - 当条件意外地显着降低性能时

c# - 如何通过存储库模式执行聚合操作?

php - 如何更改 symfony 2 doctrine 映射器以使用我的自定义目录而不是包下的实体目录

javascript - 使用 javascript 自动提交 asp.net 表单

asp.net - SendGrid 营销电子邮件延迟?

c# - 加载时更改页面 css 文件

c# - C#SqlDataReader引发语法错误,但是命令在SQL Server中运行正常?

javascript - 使用 JavaScript 将 ajax 日历值转换为文本框模糊事件中的日期时间

sql-server - 是否可以从表的列中删除非聚集索引?

c# - 将 ODATA $expand 查询选项与 WebAPI 和 ViewModel 结合使用