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

如何在泛型UnitOfWork类中正确使用ThenInclude方法?

解决泛型Repository中UnitOfWork查询方法无法调用ThenInclude的问题

当前你的FindByConditionAsync方法通过params Expression<Func<TEntity, object>>[] includes参数处理关联数据加载,但这种方式仅支持添加一级导航属性的Include,无法实现ThenInclude的链式导航加载——因为ThenInclude依赖前一个Include返回的导航属性上下文,数组形式的参数无法传递这种链式依赖关系。

解决方案:改用委托构建查询链

修改方法,将includes参数替换为Func<IQueryable<TEntity>, IQueryable<TEntity>>类型的委托,让调用者自行构建包含Include和ThenInclude的完整查询逻辑。这种方式灵活性极强,还能支持其他查询配置(如AsNoTracking)。

修改后的代码

public async Task<IEnumerable<TEntity>> FindByConditionAsync(
    Expression<Func<TEntity, bool>> filter = null,
    Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
    Func<IQueryable<TEntity>, IQueryable<TEntity>> includeBuilder = null)
{
    IQueryable<TEntity> query = dbSet;

    // 处理关联加载(支持Include+ThenInclude链式调用)
    if (includeBuilder != null)
    {
        query = includeBuilder(query);
    }

    if (filter != null)
    {
        query = query.Where(filter);
    }

    if (orderBy != null)
    {
        query = orderBy(query);
    }

    return await query.ToListAsync();
}

调用示例

调用时直接在includeBuilder委托里链式编写Include和ThenInclude:

var result = await yourRepository.FindByConditionAsync(
    filter: e => e.Id == 1,
    includeBuilder: q => q.Include(e => e.OrderItems)
                          .ThenInclude(oi => oi.Product)
                          .Include(e => e.Customer)
);

兼容原有调用的可选方案

如果需要保留原有includes参数的调用方式,可以重载方法,同时兼容新旧逻辑:

// 原有方法,兼容旧调用
public async Task<IEnumerable<TEntity>> FindByConditionAsync(
    Expression<Func<TEntity, bool>> filter = null,
    Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
    params Expression<Func<TEntity, object>>[] includes)
{
    return await FindByConditionAsync(
        filter,
        orderBy,
        q => includes.Aggregate(q, (current, include) => current.Include(include))
    );
}

// 新增的支持ThenInclude的方法
public async Task<IEnumerable<TEntity>> FindByConditionAsync(
    Expression<Func<TEntity, bool>> filter = null,
    Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
    Func<IQueryable<TEntity>, IQueryable<TEntity>> includeBuilder = null)
{
    IQueryable<TEntity> query = dbSet;

    if (includeBuilder != null)
    {
        query = includeBuilder(query);
    }

    if (filter != null)
    {
        query = query.Where(filter);
    }

    if (orderBy != null)
    {
        query = orderBy(query);
    }

    return await query.ToListAsync();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 05:36:17