2010-08-23 29 views
17

Điều này dành cho Khuôn khổ thực thể cho .NET 3.5:Lọc bảng "Bao gồm" trên truy vấn Khung thực thể

Tôi có nhu cầu truy vấn một bảng và bao gồm tập hợp bảng "nhiều" của một -many mối quan hệ. Tôi đang cố gắng lọc bộ sưu tập đó như là một phần của truy vấn - Tôi khá mới đối với Entity Framework và tôi đang gặp khó khăn trong việc tìm ra nó.

Ví dụ đơn giản: Tác giả có Sách và Sách có cột IsFiction. Tôi muốn một danh sách các tác giả được lọc, cùng với tất cả các cuốn tiểu thuyết.

Nếu không có bộ lọc, thật dễ dàng:

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

Tôi có thể lọc sau khi thực tế, một cái gì đó như:

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

Nhưng vấn đề là các truy vấn ban đầu đã chạy, và bao gồm những kết quả , đó là xử lý cơ sở dữ liệu không cần thiết.

Tôi có thể truy vấn riêng biệt, như:

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; 
} 

Nhưng tất nhiên đó là một cuộc gọi cho mỗi tác giả, mà tôi muốn tránh là tốt.

tôi có thể đi thụt lùi, như:

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

Nhưng sau đó tôi trở lại vấn đề ban đầu, ngoại trừ bây giờ ở phía tác giả thay vì phía cuốn sách.

Có phải là một giải pháp mà bao gồm tất cả mọi thứ - Tôi có thể làm điều đó trong SQL khá dễ dàng:

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

Bất kỳ lời đề nghị?

+3

Bỏ phiếu cho bộ lọc Bao gồm [ở đây] (https://entityframework.codeplex.com/workitem/47)! – Chris

Trả lời

14

Con đường phía trước:

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

Một cách khác, xuất phát từ SQL ở dưới cùng của câu hỏi của bạn:

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 }; 

Sự khác biệt chính giữa hai là người đầu tiên về cơ bản sẽ cung cấp cho bạn một tập hợp các tác giả cộng với danh sách các cuốn tiểu thuyết cho mỗi tác giả (có thể trống); trong khi thứ hai sẽ cung cấp cho bạn một bộ sưu tập các cặp tác giả/sách (vì vậy nó không trả lại bất kỳ tác giả nào không có sách hư cấu).

+0

Cảm ơn ý tưởng. Tôi hy vọng sẽ thực sự có được một bộ sưu tập các đối tượng Tác giả nếu có thể, không phải các đối tượng đã nhập ẩn danh. Trên cùng một lưu ý, nếu tôi đã thực hiện đối tượng được nhập ẩn danh đó và liệt kê bộ sưu tập Sách của tác giả, nó sẽ không trả lại toàn bộ bộ sưu tập sách, không chỉ là những cuốn sách hư cấu? –

+0

@Joe Enos: Nếu bạn liệt kê bộ sưu tập 'Sách' của' Tác giả', vâng, tất nhiên. Đó là lý do tại sao có thuộc tính 'FictionBooks' :) – Timwi

+2

Nếu bạn đang hy vọng có được các đối tượng' Author' có bộ sưu tập 'Books' là * không rõ ràng * (vì nó được lọc theo hư cấu), thì đây không phải là cách LINQ dự định làm việc . Mỗi đối tượng 'Author' được trả về bởi một truy vấn LINQ nhằm đại diện cho thực thể' Author' trong DB, không phải là một phiên bản thay đổi của nó. – Timwi

Các vấn đề liên quan