0

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

我想看到 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);
    }
}

数据库完全正确。

D B

4

1 回答 1

0

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

于 2013-04-05T18:34:55.493 回答