0

インクルードを使用した単純な LINQ は、INNER JOIN の代わりに LEFT OUTER JOIN を使用して巨大な SQL コードを生成します。

2 つのテーブルが外部キーを介して接続されており、列 TransportPointID が null ではないため、INNER JOIN が表示されると思います。

この場合、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

4

1 に答える 1