ToList () не применяет динамически сгенерированные где предложения Asp.Net Core - PullRequest
0 голосов
/ 29 июня 2018

ToList () не применяется динамически сгенерированными, где предложения Asp.Net Core Я строю трубопровод для фильтрации. поэтому у меня есть метод, где я извлекаю iqueryable из dbcontext, это выглядит следующим образом:

 public IEnumerable<Event> Filter(EventFilterModel filterModel)
    {
        _filterManager = new EventsSelectionPipeline();
        _filterManager.Register(new EventTypeFilter(filterModel.EventTypes, _unitOfWork));

        var events = _unitOfWork.DbContext.Events;
        var filteredEvents = _filterManager.Process(events);

        return filteredEvents.ToList();
    }

Метод обработки:

public override IQueryable<Event> Process(IQueryable<Event> input)
    {
        foreach(var filter in _filters)
        {
            filter.Execute(input);
        }

        return input;
    }

EventTypeFilter:

public class EventTypeFilter : IFilter<IQueryable<Event>>
{
    private readonly IEnumerable<EnumEventType> _eventTypes;
    private readonly IUnitOfWork<ApplicationContext> _unitOfWork;

    public EventTypeFilter(IEnumerable<EnumEventType> eventTypes, IUnitOfWork<ApplicationContext> uow)
    {
        _eventTypes = eventTypes;
        _unitOfWork = uow;
    }

    public IQueryable<Event> Execute(IQueryable<Event> input)
    {
        if (_eventTypes.Any())
        {
            BinaryExpression condition = null;
            var expr = new List<Expression<Func<Event, bool>>>();
            var parameter = Expression.Parameter(typeof(Event), "ev");

            foreach(var eventType in _eventTypes)
            {
                var property = Expression.Property(parameter, "EventType");
                var propType = ((PropertyInfo)property.Member).PropertyType;
                var converter = TypeDescriptor.GetConverter(propType);

                var propertyValue = eventType;
                var constant = Expression.Constant(propertyValue);
                var valueExpression = Expression.Convert(constant, propType);
                var dynExpr = Expression.Equal(property, valueExpression);

                condition = condition == null ? dynExpr : Expression.Or(condition, dynExpr);
            }

            if(condition != null)
            {
                var predicate = Expression.Lambda<Func<Event, bool>>(condition, parameter);

                input = input.Where(predicate);
            }
        }

        return input;
    }
}

В IQueryable<Event> Process(IQueryable<Event> input) метод Execute return iqueryable с правильным количеством элементов (с применением фильтрации), но когда я применяю toList к iqueryable, он просто возвращает мне начальный набор данных без фильтрации.

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

Вы должны запомнить отфильтрованный запрос:

public override IQueryable<Event> Process(IQueryable<Event> input)
{
    foreach(var filter in _filters)
    {
        input = filter.Execute(input);
    }

    return input;
}

Если вы хотите избежать необходимости присваивать результат обратно исходному запросу, вы также можете передать запрос по ссылке:

public void Execute(ref IQueryable<Event> input)
{
    if (_eventTypes.Any())
    {
        //...

        if(condition != null)
        {
            var predicate = Expression.Lambda<Func<Event, bool>>(condition, parameter);

            input = input.Where(predicate);
        }
    }
}

//...

public override IQueryable<Event> Process(IQueryable<Event> input)
{
    foreach(var filter in _filters)
    {
        filter.Execute(ref input);
    }

    return input;
}

Это позволило бы применить фильтр более «естественным» образом, тогда как первый вариант более гибок, поскольку позволяет сохранить первоначальный запрос.

0 голосов
/ 29 июня 2018
filter.Execute(input);

это, вероятно, должно быть

input = filter.Execute(input);

В противном случае ваши фильтры не "прилипают".

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