我们注意到此查询的读取次数很高:
var var1 = "535d1a11-1c2b-467a-3333-222aaa9b1fd4";
var var2 = 117;
var test = (from t1 in contextObj.Table1
join t2 in contextObj.Table2
on t1.Column2 equals t2.Column1
join t3 in contextObj.Table3 on t2.Column2 equals t3.Column1
where t3.Column1 == var1 && t2.Column3 == var2
&& t2.Column2 == var1
select t1).ToList();
这是因为Entity Framework生成的SQL缺少联接:
exec sp_executesql N'SELECT
[Extent1].[Column1] AS [Column1],
[Extent1].[Column2] AS [Column2],
[Extent1].[Column3] AS [Column3],
[Extent1].[Column4] AS [Column4],
[Extent1].[Column5] AS [Column5],
[Extent1].[Column6] AS [Column6]
FROM [dbo].[Table1] AS [Extent1]
INNER JOIN [dbo].[Table2] AS [Extent2] ON [Extent1].[Column2] = [Extent2].[Column1]
WHERE ([Extent2].[Column2] = @p__linq__0) AND ([Extent2].[Column3] = @p__linq__1) AND ([Extent2].[Column2] = @p__linq__2)',N'@p__linq__0 nvarchar(4000),@p__linq__1 int,@p__linq__2 nvarchar(4000)',@p__linq__0=N'535d5b16-1c2b-467a-9022-933ebf9b1fd4',@p__linq__1=117,@p__linq__2=N'535d5b16-1c2b-467a-9022-933ebf9b1fd4'
数据库创建脚本:https://gist.github.com/jbouwens/85e8840d799b8178ee30feb389fbc4ac
为什么EF不包括此联接/将来我该怎么做以防止这种情况?谢谢!
答案 0 :(得分:2)
在您的查询中,where子句正在比较t3.Column1 == var1和t2.Column2 == var1,但是由于您的联接已经考虑到t3.Column1 == t2.Column2,因此EF会自动删除它假定是不需要的联接。由于表结构不是理想的,因此已确定解决方案是从table3返回一个列以强制EF联接到该表。
var test = (from t1 in contextObj.Table1new
join t2 in contextObj.Table2
on t1.Column2 equals t2.Column1
join t3 in contextObj.Table3 on t2.Column2 equals t3.Column1
where t3.Column1 == var1 && t2.Column3 == var2
select new { t1, t3.Column1 }).ToList()
答案 1 :(得分:1)
我对此表示赞同,并且EF在其查询生成中“信任”了您声明的外键,SQL Server也将这样做(如果您强制执行并检查了它们)。
由于您在查询中加入了这些列,EF会将谓词t3.Column1 == var1
转换为[Extent2].[Column3] = @p__linq__1
,并且外键保证该联接将更改行数。