Отфильтруйте таблицу "Включает" в запросе Entity Framework
Это для платформы Entity Framework для .NET 3.5:
Мне нужно запросить таблицу и включить коллекцию таблицы "many" отношения "один ко многим". Я пытаюсь отфильтровать эту коллекцию как часть запроса - я довольно новичок в 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
Вперед:
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 };
Основное различие между этими двумя состоит в том, что первый из них в основном даст вам коллекцию авторов плюс список художественных книг для каждого автора (который может быть пустым); в то время как второй даст вам коллекцию пар автор/книги (поэтому он не возвращает никаких авторов без художественных книг).