2011-11-30 6 views
5

Ho un database con queste due tabelle: Customer e CustomerStatus. CustomerStatus è una cosiddetta tabella readonly. Tutte le modifiche allo stato di un cliente danno come risultato INSERT in quella tabella. Lo stato attuale del cliente è individuabile tramite CustomerStatus.StatusTimestamp.Come includere una riga specifica da un'altra tabella con LINQ alle entità

Ora sto cercando una query LINQ su entità che carichi tutti i clienti insieme al loro stato corrente. Qualcosa come

.Include("CustomerStatus.OrderByDescending(StatusTimestamp).FirstOrDefault()").

Non ho trovato un modo corretto con EF 4.0.

mia soluzione attuale è molto brutto e utilizza 2 fasi:

passo 1: query LINQ che carica tutto lo stato (nel livello aziendale/dati):

var r = from c in db.Customers.Include("CustomerStatus") select c;

fase 2: prendere lo stato adatto da ciascun cliente nella GUI (in un ciclo in una vista MVC3):

c.CustomerStatus.OrderByDescending(i => i.StatusTimestamp).FirstOrDefault()

Qualche idea su come ciò possa essere fatto direttamente in un solo passaggio?

risposta

2

EF è più potente di quanto si dà credito per. Una delle cose che può fare è proiettare su tipi complessi all'interno di un IQueryable (cioè, in un colpo di database). Questo dovrebbe funzionare:

var data = 
    from c in db.Customers 
    select new { 
     Customer = c, 
     LastStatus = c.CustomerStatus // assuming navigation property set up right 
         .OrderByDescending(s => s.StatusTimestamp) 
         .FirstOrDefault() 
    }; 

Ora data è un IQueryable<anonymous_type>, e ogni elemento ha una proprietà Customer dando al cliente, e un LastStatus dare lo status di ultima timestamp, o null se non ci sono atti di stato per la cliente.

Puoi anche usare un tipo chiamato qui, è solo più veloce per me scriverlo in questo modo :).

+0

Funziona bene. Grazie! Attualmente lo faccio ancora in 3 passaggi, ma tutti nella BLL ora: 1: 'var q = ...'. 2: 'var l = q.ToList()' (per forzare il caricamento a vuoto dello stato). 3: 'return l.Select (i => i.Customer)' (per restituire ancora un IEnumerable e non un tipo anonimo). – mkva

-1

Qualcosa di simile ??

var r = (from c in db.Customers.Include("CustomerStatus") 
      where c.CustomerStatus.OrderByDescending(i => i.StatusTimestamp) 
      select c).FirstOrDefault() 
+0

Puoi commentare perché non è utile? –

+0

Perché non viene compilato! – AakashM

+1

Ma questo è solo un compagno di pseudocodice. Come posso sapere che cosa detengono la classe Customer e CustomerStatus? –

0

io non sono sicuro di come lo schema assomiglia ma per quanto riguarda

var query = from c in db.Customers 
      join CustomerStatus s on c.StatusTimestamp = s.StatusTimestamp 
      order by s.StatusTimestamp 
      select c; 
Problemi correlati