LINQ:Include子句在应该有一个时导致两个左连接

时间:2014-04-17 12:36:11

标签: c# sql sql-server linq entity-framework

我在LINQ查询下面使用:

    CreateObjectSet<ClientCustomFieldValue>()
.Include(scf => scf.ClientCustomField.CustomField)
.Where(str => str.PassengerTripID == passengerTripID).ToList();

与此查询对应的Sql(根据sql profiler)

exec sp_executesql

N'SELECT 
    [Extent1].[ClientCustomFieldValueID] AS [ClientCustomFieldValueID], 
    [Extent1].[ClientCustomFieldID] AS [ClientCustomFieldID], 
    [Extent1].[PassengerTripID] AS [PassengerTripID], 
    [Extent1].[DataValue] AS [DataValue], 
    [Extent1].[RowVersion] AS [RowVersion], 
    [Extent1].[LastChangeSecSessionID] AS [LastChangeSecSessionID], 
    [Extent1].[LastChangeTimeUTC] AS [LastChangeTimeUTC], 
    [Extent2].[ClientCustomFieldID] AS [ClientCustomFieldID1], 
    [Extent2].[ClientID] AS [ClientID], 
    [Extent2].[CustomFieldID] AS [CustomFieldID], 
    [Extent2].[CustomFieldSourceEnumID] AS [CustomFieldSourceEnumID], 
    [Extent2].[RequiredFlag] AS [RequiredFlag], 
    [Extent2].[ValidationRegex] AS [ValidationRegex], 
    [Extent2].[RowVersion] AS [RowVersion1], 
    [Extent2].[PassengerTripStopTypeEnumID] AS [PassengerTripStopTypeEnumID], 
    [Extent2].[LastChangeSecSessionID] AS [LastChangeSecSessionID1], 
    [Extent2].[LastChangeTimeUTC] AS [LastChangeTimeUTC1], 
    [Extent4].[CustomFieldID] AS [CustomFieldID1], 
    [Extent4].[CustomFieldCode] AS [CustomFieldCode], 
    [Extent4].[Description] AS [Description], 
    [Extent4].[RowVersion] AS [RowVersion2], 
    [Extent4].[LastChangeSecSessionID] AS [LastChangeSecSessionID2], 
    [Extent4].[LastChangeTimeUTC] AS [LastChangeTimeUTC2]
FROM    [dbo].[ClientCustomFieldValue] AS [Extent1]
LEFT OUTER JOIN [dbo].[ClientCustomField] AS [Extent2] 
    ON ([Extent2].[DeleteFlag] = 0) 
    AND ([Extent1].[ClientCustomFieldID] = [Extent2].[ClientCustomFieldID])
LEFT OUTER JOIN [dbo].[ClientCustomField] AS [Extent3] 
    ON ([Extent3].[DeleteFlag] = 0) 
    AND ([Extent1].[ClientCustomFieldID] = [Extent3].[ClientCustomFieldID])
LEFT OUTER JOIN [dbo].[CustomField] AS [Extent4] 
    ON ([Extent4].[DeleteFlag] = 0) 
    AND ([Extent3].[CustomFieldID] = [Extent4].[CustomFieldID])
WHERE ([Extent1].[DeleteFlag] = 0) 
    AND ([Extent1].[PassengerTripID] = @p__linq__0)
',N'@p__linq__0 int',@p__linq__0=96

我想知道为什么有两个左连接&#39; ClientCustomField&#39;表。请帮助我理解这一点。

1 个答案:

答案 0 :(得分:1)

这是一个假设。

第一个左连接,表示为Extent2,用于SELECT子句从ClientCustomField表中检索所有必需的字段。无论如何,无论是否有Include方法调用,都会在查询中显示此内容。

第二个左连接,表示为Extent3,用于检索CustomField表字段。正如您所看到的那样,除了为此专门创建的最后一个左连接子句之外,它不会被使用,因为它连接了CustomField的所有内容。这是由Include调用产生的东西。

显然LINQ没有检查已经加入查询的表,并且分别处理查询的每个部分,它们为每个表生成了两个左连接。