如何使用 EF Core 3.0 使多个包含更高效
Posted
技术标签:
【中文标题】如何使用 EF Core 3.0 使多个包含更高效【英文标题】:How to make multiple includes more efficient with EF Core 3.0 【发布时间】:2020-02-24 19:37:32 【问题描述】:我有一个多层次的查询,包括:
var itemsToday = DatabaseContext.Items
.Where(f => f.StartTime > DateTime.Today && f.StartTime < DateTime.Today.AddDays(1))
.Include(x => x.LocalStats).ThenInclude(x=>x.StatType1)
.Include(x => x.LocalStats).ThenInclude(x=>x.StatType2)
.Include(x => x.LocalStats).ThenInclude(x=>x.StatType3)
.Include(x => x.LocalStats).ThenInclude(x=>x.StatType4)
.Include(x => x.LocalStats).ThenInclude(x=>x.StatType5)
.Include(x => x.LocalStats).ThenInclude(x=>x.StatType6)
.Include(x => x.LocalStats).ThenInclude(x=>x.StatType7)
.Include(x => x.LocalStats).ThenInclude(x=>x.StatType8)
.Include(x => x.LocalStats).ThenInclude(x=>x.StatType9)
.Include(x => x.LocalDetails)
...
.OrderBy(f=>f.SomeOrderingCriterion);
还有比这更多的包含。当然,这会导致 EF Core 3.0 在 SQL 查询中生成 许多 连接,这意味着它需要永远执行(检索 200 条记录需要 25 多秒)。
我试过用.Include(x => x.LocalStats.StatType1)
的格式代替Include和ThenInclude,但是结果是一样的。
有什么方法可以提高效率吗?文档建议:
具有大量
Include
运算符的 LINQ 查询可能需要分解为多个单独的 LINQ 查询,以避免笛卡尔爆炸问题。
但我没有看到任何关于如何实际完成此操作的解释。
【问题讨论】:
@Silvermind 我不确定我是否完全理解你所说的,但我确实需要我包含的所有数据。有些东西我没有包括在内,因为我现在不需要它们。不幸的是,这些对象又大又复杂。 here 是他们的愿景,根据Breaking Changes - Eager loading of related entities now happens in a single query @thedarkspoon 我猜它会生成左连接?左连接太多,无法正确优化查询,这就是性能体验不佳的原因。 @thedarkspoon 你对此有什么了解吗?我也想知道有什么替代方法,因为以前的版本确实整合了这些类型的 JOIN。 @Siege21x 查看我刚刚发布的答案 :) 【参考方案1】:最终我手动编写了 SQL,但我找不到使生成的 SQL 足够高效的方法。还可以考虑考虑优化数据库,例如添加聚集索引。这大大减少了数据库时间。
【讨论】:
【参考方案2】:您应该考虑延迟加载此查询。
https://docs.microsoft.com/en-us/ef/core/querying/related-data
【讨论】:
以上是关于如何使用 EF Core 3.0 使多个包含更高效的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 FromSqlRaw 在 EF Core 3.0 中调用存储过程