显然我遗漏了 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 会这样做。太可怕了,看看执行计划就知道了:
现在让我们在 SSMS 中手动清理它并查看正确的 SQL 和执行计划:
好多了,但是我们如何让 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。如果有人知道这样做有任何问题,请告诉我。
<小时/>更新,修复了 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();
空检查不应该导致框架像这样困惑。为什么我一定要这样写呢?对我来说,这似乎是框架中的一个缺陷。这会让我的动态表达式写起来有点困难,但也许我可以找到一种方法。
导航属性仍然困惑......所以我仍然很难过。下图:
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();
最佳答案
将 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/