在理解EF (4.1)生成特定SQL查询的原因时遇到了一些问题。如下所示:
基本上我有这两个类
public class Rota
{
public int RotaId { get; set; }
public int RotaGroupId { get; set; }
public virtual RotaGroup RotaGroup { get; set; }
public int EmployeeId { get; set; }
public virtual Employee Employee { get; set; }
...和
public class RotaGroup
{
public int RotaGroupId { get; private set; }
public bool IsCurrentRota { get; set; }
...rota的映射如下:
HasKey(r => r.RotaId);
Property(r=>r.RotaId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
HasRequired(r => r.RotaGroup).WithMany()
.HasForeignKey(r => r.RotaGroupId)
.WillCascadeOnDelete(false);
HasRequired(r => r.Employee).WithMany()
.HasForeignKey(r => r.EmployeeId)
.WillCascadeOnDelete(false);..。
好的。现在执行以下linq查询:
_context.Rotas.Include(r => r.RotaGroup)
.Where(r => r.EmployeeId == 1 && r.RotaGroup.IsCurrentRota)
.ToList();生成以下SQL:
SELECT ...columns...
FROM [dbo].[Rota] AS [Extent1]
INNER JOIN [dbo].[RotaGroup] AS [Extent2] ON [Extent1].[RotaGroupId] = [Extent2][RotaGroupId]
LEFT OUTER JOIN [dbo].[RotaGroup] AS [Extent3] ON [Extent1].[RotaGroupId] = [Extent3].[RotaGroupId]
WHERE ([Extent2].[IsCurrentRota] = 1) AND ([Extent1].[MyIgluUserId] = 1我相信你能看到问题所在。为什么,为什么它要在rotaGroup上连接(它应该这样),然后做一个左外部连接?此外,没有使用Extent2中的列。仅使用来自左外部联接位(Extent3)的列。
发布于 2011-06-30 17:10:38
使用[Extent2] -它是SQL的WHERE的一部分。查询的结果将是正确的,但性能可能会更差。我不认为SQL server会对此进行优化以消除不必要的左连接。
这就是EF生成查询的方式。据我所知,EF不跟踪实体集的使用情况,因此这两个查询部分Include(r => r.RotaGroup)和Where(r => r.RotaGroup.IsCurrentRota)彼此不相关。左连接是Include的结果,内连接是Where的结果。您可以尝试修改查询,使带有Include的部分成为筛选的子查询,但我怀疑它是否会以不同的方式工作。
发布于 2011-10-28 21:50:02
我遇到了一个类似的问题,即在不需要多个连接时生成多个连接(即,SQL查询可以很容易地更改为只包含一个到父表的内部连接,而不是同时包含到父表的内部连接和左连接)。
我的问题还在于测试多个值是否相等(例如,where child.ParentID == 1 || child.ParentID == 2 || child.ParentID == 3),这会创建一个混乱的where子句(其中tbl1和tbl2是添加到SELECT语句中的内部和左连接的表):
其中tbl1.ParentID =1或tbl2.ParentID IN (2,3)
这两个问题都在2011年6月的CTP包中得到了纠正:Entity framework CTP - June 2011
https://stackoverflow.com/questions/6532390
复制相似问题