2013-04-05 66 views
0

簡單的LINQ與包括產生巨大的SQL代碼與LEFT OUTER JOIN而不是INNER JOIN。EF CodeFirst TPH不會生成Inner Join?

我想看到INNER JOIN,因爲兩個表通過外鍵連接,列TransportPointID不爲空。

任何想法如何強制EF在這種情況下使用INNER JOIN?

var stops = context.TransportObjects.OfType<Stop>() 
            .Include(s => s.Points).ToList(); 
SELECT [Project1].[TransportObjectID] AS [TransportObjectID], 
     [Project1].[Type]    AS [Type], 
     [Project1].[Name]    AS [Name], 
     [Project1].[InternalName]  AS [InternalName], 
     [Project1].[C1]     AS [C1], 
     [Project1].[Type1]    AS [Type1], 
     [Project1].[TransportPointID] AS [TransportPointID], 
     [Project1].[TransportObjectID1] AS [TransportObjectID1], 
     [Project1].[Name1]    AS [Name1], 
     [Project1].[StandName]   AS [StandName] 
FROM  (SELECT [Extent1].[TransportObjectID] AS [TransportObjectID], 
       [Extent1].[Name]    AS [Name], 
       [Extent1].[InternalName]  AS [InternalName], 
       [Extent1].[Type]    AS [Type], 
       [Extent2].[TransportPointID] AS [TransportPointID], 
       [Extent2].[TransportObjectID] AS [TransportObjectID1], 
       [Extent2].[Name]    AS [Name1], 
       [Extent2].[StandName]   AS [StandName], 
       [Extent2].[Type]    AS [Type1], 
       CASE 
        WHEN ([Extent2].[TransportPointID] IS NULL) THEN CAST(NULL AS int) 
        ELSE 1 
       END AS [C1] 
      FROM [CentralDatabase].[TransportObjects] AS [Extent1] 
       LEFT OUTER JOIN [CentralDatabase].[TransportPoints] AS [Extent2] 
        ON ([Extent2].[Type] IN (CAST('2' AS smallint),CAST('1' AS smallint))) 
         AND ([Extent1].[TransportObjectID] = [Extent2].[TransportObjectID]) 
      WHERE [Extent1].[Type] IN (CAST('1' AS smallint),CAST('2' AS smallint))) AS [Project1] 
ORDER BY [Project1].[TransportObjectID] ASC, 
     [Project1].[C1] ASC 

型號

public enum TransportObjectType : short 
{ 
    Stop = 1, 
    ReferenceObject = 2 
} 

public abstract class TransportObject 
{ 
    public int TransportObjectID { get; set; } 
    public string Name { get; set; } 
    public virtual List<TransportPoint> Points { get; set; } 
} 

public class Stop : TransportObject 
{ 
    public string InternalName { get; set; } 
} 

public enum TransportPointType 
{ 
    StopPoint = 1, 
    ReferencePoint = 2 
} 

public abstract class TransportPoint 
{ 
    public int TransportPointID { get; set; } 
    public int TransportObjectID { get; set; } 
    public virtual TransportObject TransportObject { get; set; } 
    public string Name { get; set; } 
} 

public class StopPoint : TransportPoint 
{ 
    public string StandName { get; set; } 
} 

映射(只是重要的部分)

public class TransportObjectMap : EntityTypeConfiguration<TransportObject> 
{ 
    public TransportObjectMap() 
    { 
     this.Map<Stop>(m => m.Requires("Type").HasValue((short)TransportObjectType.Stop)) 
      .Map<ReferenceObject>(m => m.Requires("Type").HasValue((short)TransportObjectType.ReferenceObject)); 
    } 
} 

public class TransportPointMap : EntityTypeConfiguration<TransportPoint> 
{ 
    public TransportPointMap() 
    { 
     this.Map<StopPoint>(m => m.Requires("Type").HasValue((short)TransportPointType.StopPoint)) 
      .Map<ReferencePoint>(m => m.Requires("Type").HasValue((short)TransportPointType.ReferencePoint)); 

     // Add not nullable FK 
     this.HasRequired(o => o.TransportObject) 
      .WithMany(p => p.Points) 
      .HasForeignKey(p => p.TransportObjectID); 
    } 
} 

數據庫是完全正確的。

DB

+0

在這裏回答的類似問題http://stackoverflow.com/questions/11606044/include-and-where-predicate-cause-left-join-instead-of-inner-join – Satish 2013-04-05 20:59:06

回答

0

我認爲它需要左外連接,因爲如果你有一個TransportObject沒有任何TransportPoint的TransportObject不會被列入結果,並根據您的LINQ查詢要在所有TransportObjects名單。