LINQ to Entity: usando Contains in & # 8220; seleziona & # 8221; la porzione genera un errore imprevisto
-
03-07-2019 - |
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
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.