我必须优化我的实体框架查询,因为生成的SQL由于多个.Include(...)
语句而变得越来越复杂。
我开始使用显式加载而不是使用Includes,这很好,因为我有一些小表,最好由QueryableExtensions的Load方法显式加载。
但是,我找不到一种简单的方法来显式加载多对多连接表的映射表 - 因为映射表没有映射到DbSet ......
我使用Code First和这样的映射:
modelBuilder.Entity<SomeEntity>()
.HasMany(a => a.SomeProperty)
.WithMany()
.Map(c =>
{
c.ToTable("MappingTable");
});
有没有简单的方法来明确加载MappingTable而不映射它们?
答案 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语句等等)
此解决方案也优于显式加载整个映射表(这是我的第一个想法 - 请参阅原始问题),因为在某些情况下映射表可能非常大。