2011-08-23 15 views
11

Considerate:LINQ to Entities + Includere tipo + Anonymous problema

classe Client

Classe Progetto

Classe biglietteria

Classe Rispondi

I clienti hanno una collezione sub di progetti, i progetti hanno una sotto raccolta di biglietti e i biglietti hanno una sotto raccolta di risposte.

var data = ctx.Set<Ticket>().Include(p => p.Client). 
Select(p => new { Ticket = p, LastReplyDate = p.Replies.Max(q => q.DateCreated)}); 

Non funziona. Né il progetto né il cliente vengono caricati quando si selezionano i dati in questo modo.

So come farlo funzionare. La mia domanda è: perché non funziona così?

risposta

10

Come menzionato da Ladislav, Include funziona solo se si seleziona direttamente l'entità Ticket. Poiché stai proiettando altre informazioni, lo Include viene ignorato.

Ciò dovrebbe fornire un buon work-around:

var data = ctx.Set<Ticket>() 
    .Select(p => new 
     { 
      Ticket = p, 
      Clients = p.Client, 
      LastReplyDate = p.Replies.Max(q => q.DateCreated) 
     }); 

Prima di tutto, i clienti di ogni biglietto sarà accessibile direttamente dalla proprietà Clients sul tipo anonimo. Inoltre, Entity Framework dovrebbe essere abbastanza intelligente da riconoscere che hai estratto l'intera collezione Client per ogni Ticket, quindi chiamare lo .Ticket.Client dovrebbe funzionare anche.

+0

Grazie. Questa è anche la soluzione a cui ho pensato. – Jeroen

+2

+1 per fornire effettivamente una soluzione :) – bernhof

+0

Dovrei indicare a chiunque legge questa soluzione che EF non riempie magicamente la proprietà di navigazione '.Ticket.Client' con le entità restituite con questa proiezione, quindi l'accesso ai client tramite l'oggetto Ticket interrogherà nuovamente il database. –

5

Perché Include funziona solo se si seleziona direttamente le entità. Una volta eseguita la proiezione, Include viene ignorata. Non ti dirò perché, ma funziona semplicemente in questo modo.

+0

Pensi che Microsoft prevede di cambiare la situazione? – billy

+0

plus1 * Non ti dirò perché, ma funziona semplicemente in questo modo. * –

2

Un'altra possibilità è quella di utilizzare la soluzione di StriplingWarrior ma poi ripulire i dati intermedi dal risultato finale:

var data = ctx.Set<Ticket>() 
    .Select(p => new 
     { 
      Ticket = p, 
      Clients = p.Client, 
      LastReplyDate = p.Replies.Max(q => q.DateCreated) 
     }) 
    .AsEnumerable() 
    .Select(p => new 
     { 
      Ticket = p.Ticket, 
      LastReplyDate = p.LastReplyDate 
     }); 
Problemi correlati