Как мы можем выполнить фильтрацию объектов в Entity Framework? - PullRequest
5 голосов
/ 17 мая 2011

При определении контекста объекта, сначала используйте код в рамках сущности, например:

public class DomainContext : DbContext
{
    public DomainContext() { }
    public virtual DbSet<News> News { get; set; }
}

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

var ctx = new DomainContext();
ctx.News.Where(x => x.PublishedDate == DateTime.Now.Date)

Но, и вот в чем вопрос: есть ли способ применить предопределенную фильтрацию / условие ко всем запросам, которые проходят через ctx.News? Скажите, что я хотел, чтобы во всех запросах на ctx.News применялась неявная фильтрация «Опубликован сегодня»?

Ответы [ 4 ]

3 голосов
/ 17 мая 2011

Нет способа добавить автоматическое условие (фильтр) в запрос новостей. Все опубликованные примеры работают, но только если вы запросите News напрямую. Если вы, например, загружаете свойство навигации, указывающее на News, примеры потерпят неудачу.

EDMX решает эту проблему с помощью условного отображения , но это приводит к другим очень плохим недостаткам. Условное сопоставление является фиксированным (не может быть изменено без пересоздания модели), и вы можете иметь только одно условие для каждого типа - это похоже на TPH, пониженное до одного типа сущности. Более того, условия, определенные в условном отображении, вероятно, не могут работать с «Сегодня». Условное отображение недоступно в подходе с первым кодом.

2 голосов
/ 17 мая 2011

Я не верю, что есть способ добавить фильтр к объекту DbSet<News>, как вы предлагаете.Но то, что вы должны сделать, это просто написать другую функцию:

public virtual IEnumerable<News> TodaysNews
{
    get { return News.WHere(n => n.PublishDate == DateTime.Today); } 
}

И затем, я думаю, если вы сделали запрос поверх этого где-то еще, например:

var todaysGoodNews = from n in ctx.TodaysNews
                     where n.IsGood == true
                     select n;

тогда он будет объединять запросы при отправке его на сервер, а не делать два отдельных запроса.Я не уверен, что это работает, когда вы используете IEnumerable<> или если вам нужно вернуть что-то еще (IQueryable<>, возможно?).

Редактировать:

Я только что видел ваш ответ на другой постер ниже.Я думаю, я слишком долго печатал / форматировал.Я не знаю ни одного способа применения такого фильтра, но разве наши решения не делают это эффективно?Вы даже можете сделать TodaysNews единственным способом прямого доступа к этому объекту через контекст или что-то в этом роде.

0 голосов
/ 15 июня 2017

Я столкнулся с той же проблемой, и нашел это: EntityFramework.Filters . Этот пост показывает, как его использовать.

0 голосов
/ 17 мая 2011

Вы можете добавить новое свойство в свой контекст:

public IEnumerable<News> TodaysNews
{
    get
    {
        return this.News.Where(x => x.PublishedDate == DateTime.Now.Date);
    }
}

Любая дополнительная фильтрация / сортировка / и т. Д. Затем может быть применена к свойству.

Обновление:

Если вы не можете просто использовать предварительно отфильтрованный запрос, другой вариант - создать представление в вашей базе данных и сопоставить вашу сущность с этим представлением.Представление может быть основано на текущей дате.

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