2011-01-31 8 views
5

Questa query restituisce Id dipendente, nome, ID azienda, nome azienda e città della società. Mi manca l'indirizzo e-mail del dipendente (indirizzo e-mail memorizzato nella tabella EmployeeEmailAddress) e i numeri di telefono dei dipendenti (numero di telefono memorizzato nella tabella EmployeePhoneNumbers)..SelezionaMany() e recupera dati da più di una tabella correlata

Avevo bisogno di aggiungere il .SelectMany() per ottenere la relazione della società madre e accedere all'ID, al nome e alla città della società. Ora, tuttavia, non posso accedere a nessuna proprietà non trovata nella tabella PersonOrgMap. Non riesco a navigare verso nessun altro tavolo. La rimozione di .SelectMany() mi consente di spostarmi su altri tavoli, ma perdo l'accesso alle informazioni della società madre.

var employees = Contacts.Where(c => c.ContactAttributes 
.Any (ca => ca.AttributeID == 1153)) 
.SelectMany (x => x.ChildPersonOrgMaps) 
.Select (c => new { employeeId = c.Child.ContactID, 
      c.Child.FirstName, 
      c.Child.LastName, 
      companyId = c.ParentContactID, 
      c.Parent.OrganizationName, 
      c.Parent.City 
     } 
     ) 
.OrderBy (c =>c.LastName).ThenBy(x => x.FirstName) 
.Dump(); 

risposta

5

Qui è dove le espressioni di query sono di grande aiuto. Se si avvia la query come questa:

from c in Contacts 
where c.ContactAttributes.Any (ca => ca.AttributeID == 1153)) 
from om in c.ChildPersonOrgMaps 
... 

si avrà accesso ad entrambi i c e om variabili più tardi nella query. C# traduce questo in una chiamata SelectMany selezionando in un tipo anonimo temporaneo che "trasporta" la variabile originale. Il modo migliore per vedere questo è scrivere la query come un'espressione di query in LINQPad, quindi esaminare la scheda lambda per vedere la traduzione in sintassi fluente.

+4

+1 per lo spudorato plug LINQPad ;-) Prodotto molto bello! – DenaliHardtail

0

Sono d'accordo con Joe Albahari: utilizzare la sintassi della query. Questa è l'unica cosa (di cui sono a conoscenza) che puoi eseguire con query che non puoi con la sintassi del metodo.

Si potrebbe provare a selezionare in un tipo anonimo che contiene i propri oggetti padre e figlio, ma non credo che a EF piacerà molto.

var employees = Contacts.Where(c => c.ContactAttributes 
.Any (ca => ca.AttributeID == 1153)) 
.SelectMany (x => new { Parent = x, Child = x.ChildPersonOrgMaps }) 
// etc 
16

Se siete appassionati di sintassi metodo, poi c'è un sovraccarico SelectMany(), che dà anche accesso sia alla "fonte" e "Risultato" oggetti:

.SelectMany(x => x.ChildPersonOrgMaps, (x, c) => new { x, c }) 
.Select(xc => new 
{ 
    xc.x.Attribute1, 
    xc.x.Attribute2, 
    xc.c.Child.Attribute3, 
    xc.c.Attribute4 
}); 
Problemi correlati