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

EF Core使用AsSplitQuery后Include中OrderBy排序失效如何解决

问题原因

EF Core 7及更早版本存在已知限制:拆分查询(AsSplitQuery())模式下,Include/ThenInclude链式调用中附加的OrderBy排序、过滤逻辑会被忽略,无法下推到子查询中执行,因此你写的排序规则不会生效。

解决方案

方案1:升级EF Core版本(最推荐)

EF Core 8及以上版本已经修复了该问题,你原有的代码无需修改,保留AsSplitQuery()即可同时解决多集合包含的性能警告、正常生效导航属性的排序规则。

方案2:配置导航属性默认排序(适用于EF Core 6+)

如果暂时无法升级EF Core版本,可以在DbContext的OnModelCreating方法中配置对应导航属性的默认排序规则,不需要在查询的Include中额外编写OrderBy:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // 配置Board的Lists集合默认按Order字段升序
    modelBuilder.Entity<Board>()
        .HasMany(b => b.Lists)
        .WithOrderBy(l => l.Order);
    
    // 配置List的Items集合默认按Order字段升序
    modelBuilder.Entity<List>()
        .HasMany(l => l.Items)
        .WithOrderBy(i => i.Order);
}

配置完成后,查询代码简化为:

public async Task<Board> GetBoardAsync (Guid id) 
{ 
    return await _context.Boards
        .Include(x => x.Lists)
        .ThenInclude(x => x.Items)
        .AsSplitQuery()
        .FirstOrDefaultAsync(x => x.Id == id); 
}

方案3:查询后手动内存排序

如果不想修改模型配置,也可以在查询拿到结果后,手动对内存中的导航集合做排序:

public async Task<Board> GetBoardAsync (Guid id) 
{ 
    var board = await _context.Boards
        .Include(x => x.Lists)
        .ThenInclude(x => x.Items)
        .AsSplitQuery()
        .FirstOrDefaultAsync(x => x.Id == id); 

    if (board != null)
    {
        board.Lists = board.Lists.OrderBy(x => x.Order).ToList();
        foreach (var list in board.Lists)
        {
            list.Items = list.Items.OrderBy(x => x.Order).ToList();
        }
    }
    return board;
}

注意:如果导航集合的数据量极大,该方案会产生额外的内存开销,更推荐使用前两种方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 22:30:04