EF Code First TPH不生成内部连接?

时间:2013-04-05 17:49:27

标签: sql entity-framework ef-code-first

带有include的简单LINQ使用LEFT OUTER JOIN而不是INNER JOIN生成巨大的SQL代码。

我想看看INNER JOIN,因为两个表是通过外键连接的,而且TransportPointID列不是null。

在这种情况下如何强制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

1 个答案:

答案 0 :(得分:0)

我认为它需要左外连接,因为如果你有一个没有任何TransportPoint的TransportObject,则TransportObject不会包含在结果中,并且根据你的linq查询,你想要列表中的所有TransportObjects。