2013-09-21 18 views
109

sto ottenendo questo errore per la query di seguitoImpossibile creare un valore costante di tipo Solo tipi primitivi o tipi di enumerazione sono supportati in questo contesto

Impossibile creare un valore costante di tipo API.Models.PersonProtocol. Solo tipi o tipi di enumerazione primitivo sono supportati in questo contesto

ppCombined sotto è un IEnumerable oggetto di PersonProtocolType, che è costruito da concat di 2 PersonProtocol liste.

Perché questo non funziona? Non possiamo usare la clausola LINQ JOIN all'interno di di un JOIN?

var persons = db.Favorites 
    .Where(x => x.userId == userId) 
    .Join(db.Person, x => x.personId, y => y.personId, (x, y) => 
     new PersonDTO 
     { 
      personId = y.personId, 
      addressId = y.addressId,     
      favoriteId = x.favoriteId, 
      personProtocol = (ICollection<PersonProtocol>) ppCombined 
       .Where(a => a.personId == x.personId) 
       .Select(b => new PersonProtocol() 
       { 
        personProtocolId = b.personProtocolId, 
        activateDt = b.activateDt, 
        personId = b.personId 
       }) 
     }); 
+0

correlate: [ LINQ, impossibile creare un valore costante di tipo XXX. In questo contesto sono supportati solo tipi primitivi o tipi di enumerazione] (http://stackoverflow.com/q/13405568/456814). –

+0

Correlati: [Impossibile creare un valore costante - solo i tipi primitivi] (http://stackoverflow.com/q/10862491/456814). –

risposta

157

Questo non può funzionare perché ppCombined è una collezione di oggetti in memoria e non si può partecipare a una serie di dati nel database con un altro insieme di dati in memoria. Si può provare invece di estrarre gli elementi filtrati personProtocol della collezione ppCombined in memoria dopo aver recuperato gli altri oggetti di database:

var persons = db.Favorites 
    .Where(f => f.userId == userId) 
    .Join(db.Person, f => f.personId, p => p.personId, (f, p) => 
     new // anonymous object 
     { 
      personId = p.personId, 
      addressId = p.addressId, 
      favoriteId = f.favoriteId, 
     }) 
    .AsEnumerable() // database query ends here, the rest is a query in memory 
    .Select(x => 
     new PersonDTO 
     { 
      personId = x.personId, 
      addressId = x.addressId, 
      favoriteId = x.favoriteId, 
      personProtocol = ppCombined 
       .Where(p => p.personId == x.personId) 
       .Select(p => new PersonProtocol 
       { 
        personProtocolId = p.personProtocolId, 
        activateDt = p.activateDt, 
        personId = p.personId 
       }) 
       .ToList() 
     }); 
+3

La parte fondamentale per me è stata l'aggiunta di query .AsEnumerable() // database termina qui, il resto è una query in memoria – Sameer

+2

@Slauma Quindi, se sono preoccupato per le prestazioni, dovrei evitare di farlo poiché caricare tutti i dati in memoria prima e poi interrogarlo. Dovrei scrivere sql raw per questo scenario? – Arvand

+0

Sembra che @Arvand abbia un grande vantaggio. Se si dispone di un numero elevato di record prima del filtro, questo potrebbe richiedere un enorme morso delle risorse di memoria disponibili. – spadelives

2

Non so se qualcuno cerca per questo. Ho avuto lo stesso problema. Una selezione sulla query e poi il dove (o join) e l'uso della variabile select hanno risolto il problema per me. (problema era nella collezione "Reintegraties" per me)

query.Select(zv => new 
      { 
       zv, 
       rId = zv.this.Reintegraties.FirstOrDefault().Id 
      }) 
      .Where(x => !db.Taken.Any(t => t.HoortBijEntiteitId == x.rId 
              && t.HoortBijEntiteitType == EntiteitType.Reintegratie 
              && t.Type == TaakType)) 
      .Select(x => x.zv); 

speranza che questo aiuta nessuno.

+5

'zv.this.Reintegraties.FirstOrDefault(). Id' potenziale NullReferenceException –

0

Nel mio caso, sono stato in grado di risolvere il problema nel modo seguente:

ho cambiato il mio codice da questo:

var r2 = db.Instances.Where(x => x.Player1 == inputViewModel.InstanceList.FirstOrDefault().Player2 && x.Player2 == inputViewModel.InstanceList.FirstOrDefault().Player1).ToList(); 

A tal:

var p1 = inputViewModel.InstanceList.FirstOrDefault().Player1; 
var p2 = inputViewModel.InstanceList.FirstOrDefault().Player2; 
var r1 = db.Instances.Where(x => x.Player1 == p1 && x.Player2 == p2).ToList(); 
Problemi correlati