LINQ to Entity: usando Contains in & # 8220; seleziona & # 8221; la porzione genera un errore imprevisto

StackOverflow https://stackoverflow.com/questions/802159

Domanda

Ho una query LINQ che va contro un oggetto Entity Framework. Ecco un riepilogo della query:

//a list of my allies
List<int> allianceMembers = new List<int>() { 1,5,10 };

//query for fleets in my area, including any allies (and mark them as such)
var fleets = from af in FleetSource
             select new Fleet 
             {
                 fleetID = af.fleetID,
                 fleetName = af.fleetName,
                 isAllied = (allianceMembers.Contains(af.userID) ? true : false)
             };

Fondamentalmente, quello che sto facendo è ottenere un set di flotte. L'elenco allianceMembers contiene INT di tutti gli utenti che sono alleati con me. Voglio impostare isAllied = true se il proprietario della flotta fa parte di tale elenco e false in caso contrario.

Quando lo faccio, vedo un'eccezione: " LINQ to Entities non riconosce il metodo "Boolean Contains (Int32)" "

Posso capire come ottenere questo errore se avessi usato il contenuto nella parte in cui la query, ma perché dovrei ottenerlo nella selezione? A questo punto presumo che la query avrebbe eseguito e restituito i risultati. Questa piccola quantità di codice non fa nulla per limitare i miei dati.

Qualche consiglio su come altrimenti posso ottenere ciò di cui ho bisogno impostando la bandiera isAllied?

Grazie

È stato utile?

Soluzione

var fleets = from af in FleetSource;

var x = from u in fleets.ToList()
                         select new Fleet
                         {
                            fleetID = u.fleetID,
                            fleetName = u.fleetName,
                            isAllied = (allianceMembers.Contains(u.userID) ? true : false)
                         }

chiamando ToList () sulle flotte la query viene eseguita, in seguito puoi usare Contains () .

Altri suggerimenti

Questo è stato estratto da una risposta precedente ...

Contiene non supportato.

IN e JOIN non sono lo stesso operatore (il filtro per IN non modifica mai la cardinalità della query).

Invece di farlo in questo modo usa il metodo join. È in qualche modo difficile da capire senza usare gli operatori di query, ma una volta che lo hai, ce l'hai.

var foo = 
model.entitySet.Join(  //Start the join
values, //Join to the list of strings
e => e.Name, // on entity.Name
value => value, //equal to the string
(ModelItem ent, String str) => ent);//select the entity

Qui utilizza gli operatori di query

var foo = from e in model.entitySet
join val in values on
e.Name equals val
select e;

Fondamentalmente il framework dell'entità tenta di tradurre la tua query LINQ in un'istruzione SQL ma non sa come gestire il Contiene .

Quello che puoi fare invece è recuperare le tue flotte dal database e impostare successivamente la proprietà isAllied:

var fleets = (from af in FleetSource
              select new Fleet 
              {
                  fleetID = af.fleetID,
                  fleetName = af.fleetName,
                  userId = af.userId
              }).AsEnumerable();

foreach (var fleet in fleets)
{
    fleet.isAllied = (allianceMembers.Contains(fleet.userID) ? true : false);
}

Tutti sopra di me hanno torto !!! (Senza offesa ...) Non funziona perché stai utilizzando il sovraccarico IList di " Contiene " e non il sovraccarico IEnumerable di " Contiene " ;. Passa semplicemente a:

allianceMembers.Contains<int>(af.userID)

Aggiungendo < int > , stai dicendo al compilatore di usare il sovraccarico IEnumerable anziché il sovraccarico IList.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top