2009-04-29 5 views
1

J'ai une requête LINQ dirigée contre un objet Entity Framework. Voici un résumé de la requête:LINQ to Entity: using Contient dans la partie "select" renvoie une erreur inattendue

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

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

Quand je fais cela, je vois une exception: « LINQ to Entities ne reconnaît pas la méthode « Boolean Contient (Int32) » méthode »

Je comprends obtenir cette erreur si je l'avais utilisé le contient en la partie où de la requête, mais pourquoi l'obtenir dans le select? À ce stade, je suppose que la requête aurait été exécutée et renvoyé les résultats. Ce petit morceau de code ne fait rien pour contraindre mes données du tout.

Des conseils sur la façon dont je peux accomplir ce dont j'ai besoin pour définir le drapeau isAllied?

Merci

+1

Il convient de noter que 'Contains' * sera * pris en charge dans la prochaine version d'Entity Framework –

Répondre

-2
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 de la requête est exécutée, vous pouvez ensuite utiliser Contains().

+7

Cela ne fera-t-il pas glisser tous les objets dans la mémoire, alors qu'une méthode de travail pour faire fonctionner la requête originale ne glisserait pas dans les objets allianceMembers? –

4

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

ne contient pas pris en charge.

IN et JOIN ne sont pas les mêmes opérateurs (Filtrage par IN ne modifie jamais la cardinalité de la requête).

Au lieu de le faire de cette façon, utilisez la méthode de jointure. C'est un peu difficile à comprendre sans utiliser les opérateurs de requête, mais une fois que vous l'avez, 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; 
+0

Une jointure dans mon cas n'a aucun sens. Ce serait si j'essayais de limiter mes données en quelque sorte, mais je ne le suis pas. Le contenu se trouve dans la partie sélectionnée. – bugfixr

2

Fondamentalement, le cadre de l'entité tente de traduire votre requête LINQ dans une instruction SQL, mais ne sait pas comment gérer la Contains.

Ce que vous pouvez faire est de récupérer la place de vos flottes de la base de données et définir la propriété isAllied plus tard:

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

Tout le monde au-dessus de moi est faux !!! (Pas d'infraction ...) Cela ne fonctionne pas parce que vous utilisez la surcharge IList de "Contient" et non la surcharge IEnumerable de "Contient". il suffit de changer:

allianceMembers.Contains<int>(af.userID) 

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

+10

La raison pour laquelle ils sont au-dessus de vous est qu'ils ont tous moins de mal que vous ... –

Questions connexes