Базовый репозиторий Entity Framework, включая свойства через параметр - PullRequest
0 голосов
/ 29 декабря 2018

У меня есть реализация Generic Repository в Entity Framework, которую я пытаюсь улучшить, чтобы использовать функцию .Include (..), предоставляемую EF, вместо включения свойств навигации по строке, чтобы иметь возможность безопасно переименовыватьСвойства.

Ниже мой текущий код:

public IQueryable<T> GetAll(
        Expression<Func<T, bool>> filter = null,
        Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null,
        string includeProperties = "")
    {
        IQueryable<T> query = dbSet;

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

        foreach (var includeProperty in includeProperties.Split
            (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
        {
            query = query.Include(includeProperty);
        }

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

В настоящее время я использую это следующим образом:

repository.GetAll(
    u => u.Name = "John",
    u => u.OrderBy(x => x.Name),
    "Address.State",
);

Мой вопрос: как я могу изменитьметод, чтобы иметь возможность вызывать его следующим образом (или подобным образом):

repository.GetAll(
    u => u.Name = "John",
    u => u.OrderBy(x => x.Name),
    u => u.Include(x => x.Address).ThenInclude(x => x.State),
);

Ответы [ 3 ]

0 голосов
/ 29 декабря 2018

Я предлагаю вам оставить два метода, один из которых принимает строковые параметры, а другой - выражения.Некоторые клиенты вашего репозитория могут лучше работать с сигнатурой строки, а некоторые из них могут лучше работать с сигнатурой выражения, что дает IntelliSense для них.

public IQueryable<T> GetAll(params string[] including)
{
    var query = dbSet.AsQueryable();
    if (including != null)
        including.ToList().ForEach(include =>
        {
            if (!string.IsNullOrEmpty(include))
                query = query.Include(include);
        });
    return query;
}

public IQueryable<T> GetAll(params Expression<Func<T, object>>[] including)
{
    var query = dbSet.AsQueryable();
    if (including != null)
        including.ToList().ForEach(include =>
        {
            if (include != null)
                query = query.Include(include);
        });
    return query;
}

Убедитесь, что вы добавили using System.Data.Entity;.

Вы можете реализовать логику для фильтра и сортировать таким же образом.Для подписи строковых параметров для фильтра и сортировки можно использовать пакет System.Linq.Dynamic.

Пример:

var result1 = schoolRepository.GetAll("Students", "Teachers");
var result2 = schoolRepository.GetAll(x=>x.Students, x=>x.Teachers);
0 голосов
/ 29 декабря 2018

Вы можете использовать params Expression<Func<T, object>>[] includeProperties вместо строкового параметра

public IQueryable<T> GetAll(
    Expression<Func<T, bool>> filter = null,
    Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null,
    params Expression<Func<T, object>>[] includeProperties)
{
    IQueryable<TEntity> query = dbSet;

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

        foreach (var includeProperty in includeProperties)
        {
            query = query.Include(includeProperty);
        }

        if (orderBy != null)
        {
            return orderBy(query);
        }
        else
        {
            return query;
        }
}
0 голосов
/ 29 декабря 2018
protected internal IQueryable<TEntity> Filter(Expression<Func<TEntity, bool>> predicate, params Expression<Func<TEntity, object>>[] includeProperties)
{
    var query = RetrieveQuery();

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

    if (includeProperties != null)
    {
        query = _queryableUnitOfWork.ApplyIncludesOnQuery(query, includeProperties);
    }

    return (query);
}

И этот метод вызывается там

public IQueryable<TEntity> ApplyIncludesOnQuery<TEntity>(IQueryable<TEntity> query, params Expression<Func<TEntity, object>>[] includeProperties) where TEntity : class, IEntity
{
    // Return Applied Includes query
    return (includeProperties.Aggregate(query, (current, include) => current.Include(include)));
}

Фильтр вызова метода

 public IEnumerable<ShowStockProductDto> GetActiveShowStockProductListByProduct(int productId)
            {
                var foundedPStockroducts = Filter(
                    ent => ent.ProductId == productId && ent.IsActive,
                    ent => ent.StockProductPrices,
                    ent => ent.StockProductDepots,
                    ent => ent.StockProductSpecificationValues,
                    ent => ent.StockProductSpecificationValues.Select(spsv => spsv.SpecificationValue)
                    );

                // Map foundedPStockroducts to showStockProductList
                var showStockProductList = TypeAdapterFactory.Adapter.Adapt<IEnumerable<ShowStockProductDto>>(foundedPStockroducts).ToList();

                return (showStockProductList);
            }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...