简体   繁体   English

实体框架在多个表上左连接创建了内部连接

[英]Entity Framework left join on multiple tables creates inner join instead

I'm trying to create a query that joins four tables together, only one of which is guaranteed to exist. 我正在尝试创建一个将四个表连接在一起的查询,只有其中一个可以保证存在。 I've been successful creating left joins in EF before, but never with more than one join. 之前,我已经成功地在EF中创建了左联接,但是从来没有一个以上的联接。 Here is the query: 这是查询:

   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();

And here is the SQL that it generates. 这是它生成的SQL。 No matter what I seem to do, I always get several INNER JOIN followed by LEFT JOIN , when what I want is all LEFT JOIN . 无论我做什么,总能得到几个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'

Hoping someone can point out what I'm doing wrong here. 希望有人可以指出我在这里做错了什么。 Thanks! 谢谢!

The INNER JOINS represent required n:1 associations. INNER JOINS表示需要N:1间的关联。 If you had navigation properties, the join would be a reference to another, required, entity, not a collection. 如果您具有导航属性,则该联接将是对另一个必需实体的引用,而不是对集合的引用。 EF knows from the data model that an OUTER JOIN would have no effect here, so it generates an INNER JOIN . EF从数据模型知道OUTER JOIN在这里没有任何作用,因此它会生成INNER JOIN

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM