Как сделать динамическое включение навигационных свойств? - PullRequest
0 голосов
/ 29 апреля 2019

У меня маленькая проблема.Предполагая сущность, подобную этой

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);
}

Это прекрасно работает, но вВ реальном мире у меня есть несколько репозиториев, и я должен делать это в каждом репо, и я хотел бы сделать его динамичным.Для включения я делаю это в 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?Какие-либо предложения?Спасибо!PS: извините, мой английский ...

1 Ответ

1 голос
/ 10 мая 2019

Параметризуйте с помощью 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),
    });
...