Breeze JS - репозиторий с EFContextProvider, включающий / отключающий фильтрацию OData

Я ищу, чтобы реализовать шаблон хранилища с легким EFContextProvider. В этом репозитории я бы представил метод для запроса к БД с использованием фильтрации OData... так же, как breeze ведет себя по умолчанию. Я также хотел бы предоставить метод, который игнорировал бы фильтрацию OData и возвращал список элементов, как если бы это был контекст EF по умолчанию.

Итак, подытожив, я хотел бы попытаться сделать что-то вроде этого:

public class RepositoryBaseEntity<T> : IRepository<T> where T : class
{
        protected Breeze.WebApi.DataModelContainer _context;

        public RepositoryBaseEntity(Breeze.WebApi.EFContextProvider<DataModelContainer> context)
        {
            _context = context;
        }

        /// <summary>
        /// Gets all elements, ignoring OData filtering
        /// </summary>
        /// <returns>All elements, or null if none exists</returns>
        public IEnumerable<T> GetAll()
        {            
            // disable OData filtering in Breeze.WebApi.EFContextProvider
            return _context.Context.Set<T>();
        }


        /// <summary>
        /// Apply ODataFilters and get elements. Useful for Web API controllers
        /// </summary>
        /// <returns></returns>
        public IEnumerable<T> ApplyODataFiltersAndGet()
        {
            // enable OData filtering in Breeze.WebApi.EFContextProvider
            return _context.Context.Set<T>();
        }

}

Я взглянул на Breeze EFContextProvider, и, похоже, нет способа отключить фильтрацию OData.

Я думал о том, что, возможно, я использую старый добрый Entity Framework DataModelContainer, когда я не хочу фильтрации OData, и использую Breeze EFContextProvider обертку, когда я хочу фильтровать OData... но при таком подходе у меня будет два контекста EF... и это то, чего я хочу избежать... в прошлом в некоторых других проектах у нас были некоторые проблемы с использованием более одного контекста EF.

Итак, вы, ребята, видите какой-нибудь способ сделать это? Спасибо!

1 ответ

Решение

Фильтрация OData фактически применяется WebApi до выполнения и JSON-сериализации результата. EFContextProvider предоставляет начальный запрос, но он не применяет фильтр OData, потому что он ничего не знает о OData.

Чтобы управлять фильтрацией в WebApi, добавьте ODataQueryOptions Параметр для ваших методов контроллера WebApi. Это не позволяет WebApi применять фильтрацию и позволяет вместо этого сделать это:

public IEnumerable<Customer> Customers(ODataQueryOptions options)
{      
    if (youWantToApplyFilters)
    {
        return repository.ApplyODataFiltersAndGet(options);
    }
    else
    {
        return repository.GetAll();
    }
}

Затем в вашем хранилище,

/// <summary>
/// Apply ODataFilters and get elements. Useful for Web API controllers
/// </summary>
/// <returns></returns>
public IEnumerable<T> ApplyODataFiltersAndGet(ODataQueryOptions options)
{
    var set = _context.Context.Set<T>();
    return options.ApplyTo(set).Cast<T>();
}

Обратите внимание, что ODataQueryOptions в System.Web.Http.OData.QueryЭто означает, что ваш репозиторий будет привязан к WebApi. Если вам это не нравится, вы можете переместить фильтрацию из хранилища и ближе к контроллеру, или вы можете разделить ODataQueryOptions и поместить параметры фильтрации в свой собственный объект (но тогда вам придется применить их к запрос сам).

Другие вопросы по тегам