3

したがって、次のエンティティとそのコンテキスト構成が次のように設定されていると仮定します。簡潔にするために、多くのプロパティを省略しました。

public class Company {
    public int Id { get; set; }
    public Location Location { get; set; }
}

public class Customer {
    public int Id { get; set; }
    public Location Location { get; set; }
}

public class Location {
    public int Id { get; set; }
}

public sealed class EntityDefaultContext : DbContext {
    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.Entity<Company>().HasKey(m => m.Id).ToTable("Company");
        modelBuilder.Entity<Company>().Property(m => m.Id).HasColumnName("Id");
        modelBuilder.Entity<Company>().HasRequired(m => m.Location).WithRequiredDependent().Map(m => m.MapKey("LocationId"));

        modelBuilder.Entity<Customer>().HasKey(m => m.Id).ToTable("Customer");
        modelBuilder.Entity<Customer>().Property(m => m.Id).HasColumnName("Id");
        modelBuilder.Entity<Customer>().HasRequired(m => m.Location).WithRequiredDependent().Map(m => m.MapKey("LocationId"));

        modelBuilder.Entity<Location>().HasKey(m => m.Id).ToTable("Location");
        modelBuilder.Entity<Location>().Property(m => m.Id).HasColumnName("Id");
    }
}

ご覧のとおり、CompanyエンティティとCustomerエンティティの両方がLocationエンティティへの参照を保持しています。通常期待されることだと思います。

ご覧のとおり、DBコンテキストをそのために設定しました。しかし、EFが生成するSQLはひどく非効率的です。

SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[LocationId] AS [LocationId], 
    [Extent3].[Id] AS [Id1]
FROM
    [dbo].[Customer] AS [Extent1]
LEFT OUTER JOIN [dbo].[Company] AS [Extent2] ON [Extent1].[LocationId] = [Extent2].[LocationId]
LEFT OUTER JOIN [dbo].[Company] AS [Extent3] ON [Extent1].[LocationId] = [Extent3].[LocationId]
LEFT OUTER JOIN [dbo].[Company] AS [Extent4] ON [Extent1].[LocationId] = [Extent4].[LocationId]

これは、次のようなことをすると生成されます。

var q = from c in defaultContext.Set<Customer>().Include(m => m.Location)
        select c;

質問とは関係のない理由で、私はこのようにしています。奇妙なことに、LocationエンティティをCustomerエンティティのみによって関連付けられるように構成した場合のSQLは次のとおりです。

SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[LocationId] AS [LocationId]
FROM
    [dbo].[Customer] AS [Extent1]
INNER JOIN [dbo].[Location] AS [Extent2] ON [Extent1].[LocationId] = [Extent2].[Id]

それが私が期待することです。これは私に考えさせます。EFはこのシナリオをサポートしていませんか?どうしてできなかったの?

前もって感謝します。

4

1 に答える 1

3

元のマッピングは1対1の関係を使用します。それは常にいくつかの特別な振る舞いを引き起こします。さらに、正しく動作するためのその他の要件がいくつかあります。Customerおそらく必要なのは、andLocationCompanyandの間の1対多の関係Locationです。に変更WithRequiredDependentするWithManyと、機能するはずです。

于 2012-10-23T10:18:56.353 に答える