You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core单查询与拆分查询的选择及全局默认配置最佳实践

EF Core 单查询与拆分查询的最佳实践及常见问题解答

全局默认执行策略

EF Core 5及以上版本(包括你使用的EF Core 7)的默认执行模式为单查询(Single Query)。若要全局切换为拆分查询,可在DbContext配置中设置:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseSqlServer("YourConnectionString", 
        options => options.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery));
}

也可通过单查询上的AsSplitQuery()覆盖全局配置,或用AsSingleQuery()强制使用单查询模式。

单条记录查询场景是否始终适合拆分查询?

并非绝对,需结合数据规模判断:

  • 适合拆分查询:当单条主记录关联的多个集合数据量较大时,单查询会产生笛卡尔积,导致数据冗余、内存占用过高,拆分查询通过多次单表查询获取数据,性能更优。比如你示例中用户关联的角色、角色声明数据较多时,拆分查询更合适。
  • 不适合拆分查询:如果关联的集合数据量极小(比如每个用户仅1-2个角色,每个角色仅几个声明),单查询的笛卡尔积额外开销可忽略,一次查询即可获取所有数据,比多次数据库往返的拆分查询效率更高。

两种模式的最佳实践

单查询(Single Query)

  • 适用场景:
    • 查询主记录关联的集合数量少、数据量小的场景
    • 需要保证查询原子性(如事务中执行,避免拆分查询期间数据被修改)
    • 对数据库往返次数敏感的场景(如数据库延迟较高的环境,减少往返能提升性能)
  • 注意:包含多个集合时会触发MultipleCollectionIncludeWarning,若确认数据量小无性能问题,可通过配置抑制警告:
optionsBuilder.ConfigureWarnings(warnings => warnings.Ignore(Microsoft.EntityFrameworkCore.Diagnostics.CoreEventId.MultipleCollectionIncludeWarning));

拆分查询(Split Query)

  • 适用场景:
    • 查询包含多个大集合的关联数据,避免笛卡尔积导致的性能问题
    • 主记录数量少,但每个主记录关联的集合数据量较大的场景
  • 注意事项:
    • 拆分查询会发起多次数据库请求,可能受数据库并发修改影响(如第一次查询主记录后,关联集合数据被修改,导致数据不一致)
    • 结合Skip/Take分页时,必须保证排序条件唯一,否则多次查询可能返回不一致的分页结果。例如用主键+其他字段排序,避免相同排序值导致的记录顺序不确定:
      var users = await _userManager.Users
          .Include(x => x.UserRoles)
          .OrderBy(u => u.Id) // 主键唯一,保证排序稳定
          .Skip(10)
          .Take(5)
          .AsSplitQuery()
          .ToListAsync();
      

针对你的示例代码的建议

你的查询是获取单条用户记录及其关联的角色、角色声明,可先评估关联数据规模:

  • 若用户的角色和声明数据量不大,保留单查询即可,同时可抑制对应警告
  • 若数据量较大,AsSplitQuery()是更合适的选择,能避免笛卡尔积带来的性能损耗

内容的提问来源于stack exchange,提问作者curiousBoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 17:45:49