Отфильтруйте таблицу «Включает» в запросе Entity Framework - PullRequest
17 голосов
/ 23 августа 2010

Это для Entity Framework для .NET 3.5:

Мне нужно запросить таблицу и включить коллекцию таблицы «многие» в отношении «один ко многим».Я пытаюсь отфильтровать эту коллекцию как часть запроса - я довольно плохо знаком с Entity Framework, и у меня возникают проблемы с ее выяснением.

Упрощенный пример: у автора есть Книги, а у Книги естьКолонка IsFiction.Я хочу отфильтрованный список авторов вместе со всеми художественными книгами.

Без фильтра это легко:

var q = from a in db.Authors.Include("Books")
        where a.BirthYear > 1900
        select a;

Я могу фильтровать по факту, что-то вроде:

var fictionBooks = a.Books.Where(b => b.IsFiction);

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

Я могу запросить отдельно, например:

var q = from a in db.Authors where a.BirthYear > 1900 select a;
foreach (var a in q)
{
    var books = from b in db.Books 
                where ((b.Author.Id == a.Id) && (b.IsFiction))
                select b;
}

Ноконечно, это один вызов для каждого автора, которого я также хочу избежать.

Я могу вернуться назад, как:

var allBooks = from b in db.Books.Include("Author")
               where b.IsFiction
               select b;

Но затем я возвращаюсь к исходной проблеме,кроме теперь на стороне автора, а не на стороне книги.

Должно быть решение, которое охватывает все - я могу сделать это в SQL довольно легко:

select * from author a
left join book b on a.id = b.author_id and b.is_fiction = 1
where a.birth_year > 1900

Есть предложения?

1 Ответ

14 голосов
/ 23 августа 2010

Путь вперед:

var q = from a in db.Authors.Include("Books")
        where a.BirthYear > 1900
        select new {
            Author = a,
            FictionBooks = a.Books.Where(b => b.IsFiction)
        };

Другой способ, полученный из SQL в нижней части вашего вопроса:

var q = from a in db.Authors
        from b in db.Books.Include("Author")
        where a.BirthYear > 1900 && b.IsFiction && a.Id == b.Author.Id
        select new { Author = a, Book = b };

Основное различие между этими двумя заключается в том, что первый в основном даст вам коллекцию авторов плюс список художественных книг для каждого автора (который может быть пустым); в то время как второй даст вам коллекцию пар автор / книга (поэтому он не вернет ни одного автора без художественной литературы).

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