如何使用Entity Framework显式加载映射表?

时间:2015-11-16 12:04:36

标签: c# .net sql-server entity-framework query-optimization

我必须优化我的实体框架查询,因为生成的SQL由于多个.Include(...)语句而变得越来越复杂。

我开始使用显式加载而不是使用Includes,这很好,因为我有一些小表,最好由QueryableExtensions的Load方法显式加载。

但是,我找不到一种简单的方法来显式加载多对多连接表的映射表 - 因为映射表没有映射到DbSet ......

我使用Code First和这样的映射:

 modelBuilder.Entity<SomeEntity>()
             .HasMany(a => a.SomeProperty)
             .WithMany()
             .Map(c =>
             {
                  c.ToTable("MappingTable");
             });

有没有简单的方法来明确加载MappingTable而不映射它们?

1 个答案:

答案 0 :(得分:0)

现在我意识到Include语句在我包含多个(至少2个)具有多对多关系的字段时会生成UNION - 这似乎是合乎逻辑的,虽然起初我没看到发生了什么在后台。多个UNION的问题在于,如果查询很多,查询可能会非常复杂。

事实证明,我可以使用相同的查询过滤器“预取”多对多连接。如果我为每个多对多连接进行预取,这会简化查询(尽管它会向数据库服务器进行多次往返,但对我来说这不是一个大问题。)

所以用一个例子来说明它 - 而不是写一些像:

var query = ctx.Employee
               .Include(e => e.ContactAddresses)
               .Include(e => e.Contracts)
               .MyFilter();

query.ToList().Select(e => 
{
    ContactNames = e.ContactAddresses.Select(c => c.DisplayName),
    ContractNames = e.Contracts.Select(c => c.DisplayName)
});

写下类似的内容:

ctx.Employee.Include(e => e.ContactAddresses).MyFilter().ToList();
ctx.Employee.Include(e => e.Contracts).MyFilter().ToList();


var query = ctx.Employee
               .MyFilter();

query.ToList().Select(e => 
{
    ContactNames = e.ContactAddresses.Select(c => c.DisplayName),
    ContractNames = e.Contracts.Select(c => c.DisplayName)
});

MyFilter()包含过滤逻辑,它们是查询的一部分(Where语句等等)

此解决方案也优于显式加载整个映射表(这是我的第一个想法 - 请参阅原始问题),因为在某些情况下映射表可能非常大。