2010-08-23 19 views
17

"içerir":Filtre tablo Varlık ilişkin Çerçeve sorgu Bu .NET 3.5 için Varlık Framework içindir

Bir masa sorgulamak için ihtiyaç ve bire bir "çok" tablosunun bir koleksiyon bulunmaktadır - erkek ilişki. Bu koleksiyonu sorgunun bir parçası olarak filtrelemeye çalışıyorum - Entity Framework'e oldukça yeni yaşıyorum ve bunu çözmekte zorlanıyorum.

Basitleştirilmiş örnek: Yazarda Kitaplar var ve Kitapta bir IsFiction sütunu var. Tüm kurgu kitaplarıyla birlikte süzgeçli bir yazar listesi istiyorum.

Filtresiz

, kolay:

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

Ben aslında sonra filtreleme yapabilirsiniz, gibi bir şey: Sorun orijinal sorgu zaten koştu ve bu sonuçları dahil olmasıdır

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

Ama gereksiz veritabanı işlemesidir.

ben gibi, ayrı ayrı sorgulayabilir:

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

Ama bunun da kaçınmak istediğiniz her yazar için bir çağrı var tabii

.

ben gibi, geriye gidebilir:

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

Ama sonra yerine kitap tarafında yazarı tarafında şimdi hariç, geri orijinal probleme değilim.

şeyi kapsayan bir çözüm olmalı - Ben oldukça kolay SQL yapabilirsiniz:

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

herhangi bir öneriniz?

+3

Filtreden çıkarma için [buraya] (https://entityframework.codeplex.com/workitem/47) adresini ekleyin! – Chris

cevap

14

İleriye doğru:

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

diğer yolu da, sorunun altındaki SQL türetilen:

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

Bu ikisi arasındaki temel fark ilki temelde verecek olmasıdır yazarların bir koleksiyonu artı her yazar için kurgu kitaplarının listesi (boş olabilir); ikincisi size bir yazar/kitap çifti koleksiyonu verecektir (bu nedenle hiçbir kurgu kitabı olmayan yazarlara geri dönmez).

+0

Fikir için teşekkürler. Mümkünse, anonim yazılan nesneler olmasa bile, bir Yazar nesnesi koleksiyonu elde etmeyi umuyorum. Aynı kayda göre, ben verseydiniz kitapların tüm koleksiyonu, sadece kurgu olanlar dönmek olmaz, yani anonim yazılan nesneyi alıp Yazarın Kitapları koleksiyonunu sayılan? –

+0

@Joe Enos: “Yazar” ın “Kitap” koleksiyonunu saydıysanız, elbette. Alacağınız için umut varsa 'FictionBooks' özellik :) – Timwi

+2

var bu yüzden' Author' olan 'Books' koleksiyon * nesneleri açıkça tamamlanmamış * (o fictionness tarafından filtre çünkü), o zaman bu LINQ çalışmak için tasarlanmıştır gerçekten böyle olmaz . LINQ sorgu tarafından döndürülen her 'Author' nesne DB' Author' varlık değil, bunun değiştirilmiş bir versiyonu temsil etmesi amaçlanmıştır. – Timwi