2009-10-08 9 views
22

J'ai deux tables: une table WorkItem et une table WorkItemNote. Comment retourner un WorkItem et tous les WorkItemNotes répondant à certains critères?Requête EF avec conditionnel Inclure

Je pense que cela devrait être simple, presque comme un "Inclure" conditionnel, non?

Répondre

38

J'ai prévu d'écrire a tip à ce sujet mais votre question m'a battu au punch.

En supposant un WorkItem a beaucoup WorkItemNotes

vous pouvez le faire:

var intermediary = (from item in ctx.WorkItems 
       from note in item.Notes 
       where note.SomeProp == SomeValue 
       select new {item, note}).AsEnumerable(); 

Ceci produit un élément anonyme pour chaque WorkItemNote qui correspond, et détient le WorkItem correspondant aussi. La résolution d'identité d'EF assure que le même WorkItem (par référence) est retourné plusieurs fois s'il a plusieurs WorkItemNotes qui correspondent aux critères.

Je suppose que la prochaine que vous voulez simplement revenir à tout le WorkItems, comme ceci:

var workItems = intermediary.Select(x => x.item).Distinct().ToList(); 

Alors si vous faites maintenant ceci:

foreach(var workItem in workItems) 
{ 
    Console.WriteLine(workItem.Notes.Count) 
} 

Vous verrez que WorkItemNotes qui correspondent à le filtre d'origine a été ajouté à la collection Notes de chaque workItem.

Cela est dû à quelque chose appelé Relationship Fixup.

I.e. Cela vous donne ce que vous voulez inclure conditionnel.

Hope this helps

Alex

+0

Vraiment? x.Il aura les WorkItemNotes appropriés? C'est génial! Je suis content que vous ayez posté ceci parce que ce que j'ai actuellement interroge la base de données pour chaque WorkItem. Merci! –

+0

Une question: Pourquoi l'intermédiaire doit-il être IEnumerable? Peut-il être IQueryable? –

+0

Yeap cela fonctionne. Vous pouvez aussi l'utiliser pour d'autres trucs, comme le tri, voir Astuce 1 de ma série de conseils! –