LINQ to Entity: l'utilisation de Contains dans la partie «select» génère une erreur inattendue

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

Question

Une requête LINQ s’applique à un objet Entity Framework. Voici un résumé de la requête:

//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)
             };

En gros, ce que je fais, c'est obtenir un ensemble de flottes. La liste allianceMembers contient les INT de tous les utilisateurs qui sont alliés avec moi. Je souhaite définir isAllied = true si le propriétaire de la flotte fait partie de cette liste et false sinon.

Lorsque je le fais, je vois une exception: "LINQ to Entities ne reconnaît pas la méthode" La méthode "booléen contient (Int32)" "

Je peux comprendre que cette erreur se soit produite si j’avais utilisé le contenu de la partie où se trouve la requête, mais pourquoi devrais-je l’obtenir dans la sélection? À ce stade, je suppose que la requête s’est exécutée et a renvoyé les résultats. Ce petit bout de code ne fait rien pour contraindre mes données.

Avez-vous des conseils sur la manière d'accomplir ce que je souhaite avec la définition du drapeau isAllied?

Merci

Était-ce utile?

La solution

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)
                         }

appelant ToList () sur les flottes où la requête est exécutée, vous pouvez utiliser plus tard Contains () .

Autres conseils

Ce poché d'une réponse précédente ...

Contient non pris en charge.

IN et JOIN ne sont pas le même opérateur (le filtrage par IN ne change jamais la cardinalité de la requête).

Au lieu de procéder de cette manière, utilisez la méthode join. C'est un peu difficile à comprendre sans utiliser les opérateurs de requête, mais une fois que vous l'obtenez, vous l'avez.

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

Ici, il utilise les opérateurs de requête

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

Fondamentalement, le framework d'entités tente de traduire votre requête LINQ en une instruction SQL mais ne sait pas comment gérer le Contains .

Vous pouvez plutôt récupérer vos flottes de la base de données et définir la propriété isAllied ultérieurement:

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);
}

Tout le monde au-dessus de moi a tort !!! (Aucune infraction ...) Cela ne fonctionne pas car vous utilisez la surcharge IList de "Contains". et pas la surcharge IEnumerable de "contient". Changez simplement pour:

allianceMembers.Contains<int>(af.userID)

En ajoutant le < int > , vous indiquez au compilateur d'utiliser la surcharge IEnumerable au lieu de la surcharge IList.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top