如何动态包含导航属性?

时间:2019-04-29 07:12:22

标签: c# ef-core-2.0

我有一个小问题。 假设这样的实体

public class FirstEntity
{
    public int ID { get; set; }
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
    public virtual ICollection<SecondEntity> SecondECollection { get; set; }
}

public class SecondEntity
{
    public int ID { get; set; }
    public string Prop1 { get; set; }
    public virtual ThirdEntity Third { get; set; }
}

在存储库中,要获得具有所有导航属性的实体,我必须要做类似的事情

public IQueryable<FirstEntity> Get()
{
    return 
        _context.Set<FirstEntity>()
            .Select(t => t)
            .Include(t => t.SecondECollection)
            .ThenInclude(t => t.ThirdEntity);
}

这项工作正常,但是,在现实世界中,我有一些存储库,并且我必须在每个回购中都这样做,并且我想使其动态化。 对于Include,我已在BaseRepository中执行此操作(我的所有存储库均从此继承),并且工作正常

public IQueryable<TEntity> GetBySpecification(ISpecification<TEntity> spec = null, bool tracking = true, params Expression<Func<TEntity, object>>[] includeExpressions)
{
    var query = _context.Set<TEntity>().Select(r => r);
    if (!tracking)
        query = query.AsNoTracking();
    if (includeExpressions != null)
        foreach (var includeExpression in includeExpressions)
            query = query.Include(includeExpression);
    if (spec != null)
        query = query.Where(spec.Expression);
    return query;
}

但是我如何可以动态地制作ThenInclude? 有什么建议么? 谢谢! 附言:抱歉,我的英语...

1 个答案:

答案 0 :(得分:0)

使用Func<IQueryable<TEntity>, IQueryable<TEntity>>进行参数设置。

代替.Select(r => r),您可以简单地使用.AsQueryable()

public IQueryable<TEntity> GetBySpecification(ISpecification<TEntity> spec = null, bool tracking = true, params Func<IQueryable<TEntity>, IQueryable<TEntity>>[] includes)
{
    var query = _context.Set<TEntity>().AsQueryable();
    if (!tracking)
        query = query.AsNoTracking();
    if (includes != null)
        foreach (var include in includes)
            query = include(query);
    if (spec != null)
        query = query.Where(spec.Expression);
    return query;
}
return GetBySpecification(
    includes: new Func<IQueryable<User>, IQueryable<User>>[]
    {
        (q) => q.Include(u => u.Roles).ThenInclude(r => r.Permissions),
    });