2015-01-09 78 views
1

我试图创建一个将四个表连接在一起的查询,其中只有一个保证存在。我之前成功地在EF中创建了左连接,但从来没有多于一个连接。以下是查询:实体框架在多个表上留下的连接创建内部连接

var details = (from planInfo in context.PlanInfo 
       join templateRec in context.ProductTemplates 
        on planInfo.TemplateId equals templateRec.TemplateId into templateGroup 
       from template in templateGroup.DefaultIfEmpty() 
       join profileRec in context.CustomerProfiles 
        on planInfo.ProfileId equals profileRec.ProfileId into profileGroup 
       from profile in profileGroup.DefaultIfEmpty() 
       join territoryRec in context.Territories 
        on planInfo.TerritoryId equals territoryRec.TerritoryId into territoryGroup 
       from territory in territoryGroup.DefaultIfEmpty() 
       where planInfo.ActiveStatus 
       && planInfo.PlanId == plan.PlanId 
       select new 
       { 
        PlanId = planInfo.PlanId, 
        TemplateId = planInfo.TemplateId, 
        TemplateGridId = planInfo.TemplateId, 
        ProfileRec = (profile == null ? 
        new 
        { 
         ProfileId = 0, 
         ProfileGridId = 0, 
         Description = string.Empty 
        } : 
        new 
        { 
         ProfileId = profile.ProfileId, 
         ProfileGridId = profile.ProfileId, 
         Description = profile.Description 
        }), 
        ProfileId = (profile == null ? 0 : profile.ProfileId), 
        TerritoryRec = (territory == null ? 
        new 
        { 
         TerritoryId = 0, 
         TerritoryGridId = 0, 
         Description = string.Empty 
        } : 
        new 
        { 
         TerritoryId = territory.TerritoryId, 
         TerritoryGridId = territory.TerritoryId, 
         Description = territory.Description 
        }), 
        TerritoryId = (territory == null ? 0 : territory.TerritoryId), 
        Description = (template == null ? string.Empty: template.Description), 
        TemplateEffectiveDate = planInfo.TemplateEffectiveDate, 
        TemplateExpiryDate = planInfo.TemplateExpiryDate, 
        MinVolume = planInfo.MinVolume, 
        MaxVolume = planInfo.MaxVolume, 
        AccrualPercent = planInfo.AccrualPercent, 
        AccrualPercentNatl = planInfo.AccrualPercentNatl, 
        EffectiveDate = planInfo.EffectiveDate, 
        ExpiryDate = planInfo.ExpiryDate 
       }).ToList(); 

这里是它生成的SQL。无论我做什么,我总是得到几个INNER JOIN,然后LEFT JOIN,当我想要的全部是LEFT JOIN

SELECT 
    [Filter1].[PlanId] AS [PlanId], 
    [Filter1].[TemplateId1] AS [TemplateId], 
    [Filter1].[ProfileId1] AS [ProfileId], 
    [Filter1].[Description1] AS [Description], 
    CASE WHEN ([Extent4].[TerritoryId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1], 
    [Extent4].[TerritoryId] AS [TerritoryId], 
    [Extent4].[Description] AS [Description1], 
    CASE WHEN ([Extent4].[TerritoryId] IS NULL) THEN 0 ELSE [Extent4].[TerritoryId] END AS [C2], 
    [Filter1].[Description2] AS [Description2], 
    [Filter1].[TemplateEffectiveDate] AS [TemplateEffectiveDate], 
    [Filter1].[TemplateExpiryDate] AS [TemplateExpiryDate], 
    [Filter1].[MinVolume] AS [MinVolume], 
    [Filter1].[MaxVolume] AS [MaxVolume], 
    [Filter1].[AccrualPercent] AS [AccrualPercent], 
    [Filter1].[AccrualPercentNatl] AS [AccrualPercentNatl], 
    [Filter1].[EffectiveDate] AS [EffectiveDate], 
    [Filter1].[ExpiryDate] AS [ExpiryDate] 
    FROM (SELECT [Extent1].[PlanId] AS [PlanId], [Extent1].[TemplateId] AS [TemplateId1], [Extent1].[TerritoryId] AS [TerritoryId], [Extent1].[TemplateEffectiveDate] AS [TemplateEffectiveDate], [Extent1].[TemplateExpiryDate] AS [TemplateExpiryDate], [Extent1].[MinVolume] AS [MinVolume], [Extent1].[MaxVolume] AS [MaxVolume], [Extent1].[AccrualPercent] AS [AccrualPercent], [Extent1].[AccrualPercentNatl] AS [AccrualPercentNatl], [Extent1].[EffectiveDate] AS [EffectiveDate], [Extent1].[ExpiryDate] AS [ExpiryDate], [Extent2].[Description] AS [Description2], [Extent3].[ProfileId] AS [ProfileId1], [Extent3].[Description] AS [Description1] 
     FROM [dbo].[PlanInfo] AS [Extent1] 
     INNER JOIN [dbo].[ProductTemplates] AS [Extent2] ON [Extent1].[TemplateId] = [Extent2].[TemplateId] 
     INNER JOIN [dbo].[CustomerProfiles] AS [Extent3] ON [Extent1].[ProfileId] = [Extent3].[ProfileId] 
     WHERE [Extent1].[ActiveStatus] = 1) AS [Filter1] 
    LEFT OUTER JOIN [dbo].[Territories] AS [Extent4] ON [Filter1].[TerritoryId] = [Extent4].[TerritoryId] 
    WHERE [Filter1].[PlanId] = '12345' 

希望有人能指出我在做什么错在这里。谢谢!

+0

你可能没有*表*? – 2015-01-09 22:12:34

+2

首先是内在问题:你为什么要加入而不是使用导航属性? – 2015-01-09 22:15:40

+0

什么是“plan.PlanId”? – 2015-01-09 22:16:27

回答

0

INNER JOINS表示所需的n:1关联。如果您有导航属性,则联接将是对另一个必需实体的引用,而不是集合。 EF从数据模型中知道OUTER JOIN在这里不起作用,所以它会生成一个INNER JOIN

+0

但我可以改变哪些表得到了左连接,哪些得到了内连。如果我将连接从第一个移动到最后一个ProductTemplates,那么ProductTemplates突然获得一个左连接,而Territories(之前已经离开连接)现在获得一个内连接。 – kindwarrior 2015-01-09 23:03:13

+0

我需要了解更多关于这些关联的信息。但现在对我来说已经迟到了...... – 2015-01-09 23:23:23

+0

我不确定这些关联是否是造成初始问题的原因,但是通过向实体添加导航属性,我可以使其工作以及简化查询。感谢您的建议! – kindwarrior 2015-01-10 01:43:46