2011-10-06 13 views
9

ho un problema qui con ottenere i dati dal mio database con LINQLINQ complesso immobiliare di navigazione di query

Ho due tabelle Team e TeamMember, che sono collegati da 1-N rapporto. Sto utilizzando Entity Framework e ho un'entità per ciascuna delle tabelle con una proprietà per ogni colonna. Anche nell'entità Team esiste una proprietà di navigazione TeamMember come risultato di questa relazione.

Voglio fare una query in cui posso ottenere tutta la mia squadra con i membri del team.

result = (from t in this.context.Teams 
      orderby t.Name 
      select t) 
     .Include("TeamMembers") 

Questo funziona correttamente. Ricevo una raccolta di entità del team con la proprietà Team.TeamMember popolata con i dati del membro di ciascuna squadra.

Il problema si verifica quando si desidera eseguire una query più complessa come filtrare la query per TeamMembers.

Ad esempio, entrambe le tabelle hanno una colonna EndDateTime. Se voglio ottenere tutta la squadra e i membri del team che non sono finiti (la loro data di fine non è nulla) non so come farlo.

Con questa query filtrerò solo le squadre, ma non i membri del team.

result = (from t in this.context.Teams 
      where t.EndDateTime == null 
      orderby t.Name 
      select t) 
     .Include("TeamMembers") 
     .ToList(); 

Qualche idea?

Io tipo "risolvo" facendo il filtro del membro dopo la query, alla raccolta. Mi piace:

//Filter out the End dated care coordiantors 
var careCoordinatorsToDelete = new List<CareCoordinator>(); 
foreach (var team in result) 
{ 
    careCoordinatorsToDelete.Clear(); 

    foreach (var careCoordinator in team.CareCoordinators) 
    { 
     if (careCoordinator.EndDateTime != null) 
      careCoordinatorsToDelete.Add(careCoordinator); 
    } 

    foreach (var toDelete in careCoordinatorsToDelete) 
    { 
     team.CareCoordinators.Remove(toDelete); 
    } 
} 

Ma non penso che questa sia una buona soluzione.

+0

possibile duplicato di [include condizionale in linq per entità?] (Http://stackoverflow.com/questions/1085462/conditional-include-in-linq-to-entities) –

+0

+1 Questa è una grande domanda e una delle cose meno ovvie da fare con EF, ma è un duplicato. Penso che ci siano anche altri duplicati. –

+0

un altro duplicato: http://stackoverflow.com/questions/1680863/linq-include-with-where-clause –

risposta

1

Come ho sottolineato, penso che questo sia un duplicato. Ma riassumendo le risposte, è sufficiente includere la clausola Where sul figlio come parte dell'istruzione Select (utilizzandola come parte di un tipo anonimo), enumerare la query e quindi recuperare gli oggetti desiderati.

Poiché hai selezionato lo TeamMembers che desideri in un'altra proprietà, verranno recuperati dal database e creati nel grafico dell'oggetto.

result = (from t in this.context.Teams 
      where t.EndDateTime == null 
      orderby t.Name 
      select new 
      { 
       Team = t, 
       Members = t.TeamMembers.Where(tm => tm.EndDateTime == null) 
      }) 
     .ToList() 
     .Select(anon => anon.Team) 
     .ToList(); 
+0

Hey. Ci ho provato ma non funziona! Potrebbe essere perché ho il caricamento Lazy disattivato? –

+0

@Asier - .ToList() impone l'esecuzione della query - quindi l'esempio è carico impaziente, non carico pigro ... – barrypicker

0

questo dovrebbe funzionare:

var result = this.context.Teams.Where(t=>t.EndDateTime==null).Select(t=> 
new { Name = t.Name, 
      PropertyX = t.PropertyX... //pull any other needed team properties. 
      CareCoordinators = t.CareCoordinators.Where(c=>c.EndDateTime==null) 
}).ToList(); 

questo restituisce un elenco di oggetti anonimi.