2013-07-18 7 views
10

Ok, devo fare qualcosa di stupido, ma non dovrebbe funzionare? Ho seguito tre liste:Concatenare tre elenchi in uno con LINQ genera un'eccezione

var commonViews = (from v in context.TPM_VIEWS where v.VIEWID < 0 select v); // IQueryable<TPM_VIEWS> 
var ownedViews = (from v in context.TPM_VIEWS where v.OWNERID == userId && v.VIEWID > 0 select v); // IQueryable<TPM_VIEWS> 
var sharedViews = (from v in context.TPM_USER.Include("TPM_VIEWS2") where v.USERID == userId select v).First().TPM_VIEWS2; // EntityCollection<TPM_VIEWS> 

Ogni elenco ha i valori corretti e conteggia. Posso tornare uno di questi elenchi:

return commonViews.ToList(); 

E posso restituire un qualsiasi due di queste liste:

return commonViews.Concat(ownedViews).ToList(); 

Tuttavia, quando provo a tornare tutti e tre:

return commonViews.Concat(ownedViews).Concat(sharedViews).ToList(); 

Ho ricevuto l'eccezione:

Impossibile creare un valore costante di tipo "Entity.TPM_VIEWS". In questo contesto sono supportati solo i tipi primitivi o i tipi di enumerazione .

Cosa sto sbagliando? Tutti e tre i valori sono effettivamente enumerabili. Per lo più, sto facendo questa domanda perché è il modo migliore per garantire che noterò il problema 30 secondi dopo la pubblicazione.

UPDATE:

Sono sicuro che il 93% il problema è qui:

var sharedViews = (from v in context.TPM_USER.Include("TPM_VIEWS2") where v.USERID == userId select v).First().TPM_VIEWS2; 

Questo sembra come un elenco di enumerabile TPM_VIEWS oggetto, e posso chiamare ToList() su di esso e ottieni i dati corretti, ma non gioca bene con gli altri elenchi.

UPDATE 2:

Questo funziona realmente. Indica la persona che può dirmi perché!

commonViews.ToList().Concat(ownedViews.ToList()).Concat(sharedViews.ToList()).ToList(); 
+0

Prova a mettere prima 'sharedViews'. Sì; Sospetto seriamente che lo risolverà. – SLaks

+0

sulla base della mia storia estremamente semplice con EF, sarei disposto a scommettere un fiver @SLaks ha ragione. – JerKimball

+0

Ok si, questo è strano. 'sharedViews.Concat (commonViews) .Concat (ownedViews) .Count()' restituisce 6 (che è corretto), ma 'sharedViews.Concat (commonViews) .Concat (ownedViews) .ToList();' genera la stessa eccezione. È sicuramente qualcosa di funky con 'sharedViews'. Fondamentalmente, ho bisogno di ottenere un 'IEnumerable ' dal dato 'userId'. –

risposta

5

Il problema è che Concat() su un EF IQueryable<T> si accende l'intera concatenazione in una singola query.

Quando si chiama .Concat(sharedViews), si passa a una raccolta scalare (pre-caricata) della classe di entità nidificata.
EF non sa come convertirlo in una query, quindi si lamenta.

È possibile rendere più veloce chiamando AsEnumerable() anziché ToList().

+0

Eccellente, penso che questo riassuma tutto perfettamente! –

+0

Quindi @MikeChristensen ottiene $ 5 o no? – Kevin

+0

Accetto PayPal. –

1

Questo funziona davvero. Indica la persona che può dirmi perché!

commonViews.ToList().Concat(ownedViews.ToList()).Concat(sharedViews.ToList()).ToList(); 

Questo perché ciascuna delle domande originali viene eseguita separatamente; stai solo concatenando i risultati in memoria.Sembra che ci sia un bug nel traduttore di query Entity Framework quando si combinano le 3 query, ma quando si chiama ToList su ciascuna di esse, non sono più query EF, sono solo elenchi, quindi sono concatenati utilizzando Linq agli oggetti.

Problemi correlati