225 votes

"Une expression lambda avec un corps de déclaration ne peut pas être convertie en un arbre d'expression"

En utilisant le EntityFramework J'obtiens l'erreur " A lambda expression with a statement body cannot be converted to an expression tree " en essayant de compiler le code suivant :

Obj[] myArray = objects.Select(o =>
{
    var someLocalVar = o.someVar;

    return new Obj() { 
    Var1 = someLocalVar,
    Var2 = o.var2 };
}).ToArray();

Je ne sais pas ce que signifie cette erreur et surtout comment la réparer. Vous pouvez m'aider ?

6 votes

Essayez de convertir en liste comme ceci. objects.List().Select(...)

141voto

Tim Rogers Points 9956

Est objects un contexte de base de données Linq-To-SQL ? Dans ce cas, vous ne pouvez utiliser que des expressions simples à droite de l'opérateur =>. En effet, ces expressions ne sont pas exécutées, mais sont converties en SQL pour être exécutées dans la base de données. Essayez ceci

Arr[] myArray = objects.Select(o => new Obj() { 
    Var1 = o.someVar,
    Var2 = o.var2 
}).ToArray();

118voto

Amir Oveisi Points 371

Vous pouvez utiliser le corps de la déclaration dans une expression lamba pour IEnumerable collections. Essayez celle-ci :

Obj[] myArray = objects.AsEnumerable().Select(o =>
{
    var someLocalVar = o.someVar;

    return new Obj() 
    { 
        Var1 = someLocalVar,
        Var2 = o.var2 
    };
}).ToArray();

Avis :
Réfléchissez bien lorsque vous utilisez cette méthode, car de cette façon, vous aurez tous les résultats de la requête en mémoire, ce qui peut avoir des effets secondaires indésirables sur le reste de votre code.

4 votes

+1 J'aime ça ! Ajout de AsEnumerable() masque mon problème disparaît !

5 votes

C'est la vraie solution, la réponse acceptée est difficile à appliquer dans certains cas.

27 votes

Non, ce n'est pas la vraie réponse. Votre requête serait exécutée du côté client. Reportez-vous à cette question pour plus de détails : stackoverflow.com/questions/33375998/

42voto

sepp2k Points 157757

Cela signifie que vous ne pouvez pas utiliser des expressions lambda avec un "corps de déclaration" (c'est-à-dire des expressions lambda qui utilisent des accolades) dans les endroits où l'expression lambda doit être convertie en un arbre d'expression (ce qui est par exemple le cas lors de l'utilisation de linq2sql).

53 votes

Vous avez... légèrement reformulé l'erreur. La réponse de @Tim Rogers était bien meilleure.

4 votes

@vbullinger vous avez raison jusqu'à un certain point, mais dans un sens plus général (en dehors du contexte de linq à sql) c'est une réponse plus directe. Elle m'a aidé à résoudre une erreur d'AutoMapper.

2 votes

Vbullinger : Ça m'a aidé, cependant.

9voto

spender Points 51307

Sans en savoir plus sur ce que vous faites (Linq2Objects, Linq2Entities, Linq2Sql ?), cela devrait fonctionner :

Arr[] myArray = objects.AsEnumerable().Select(o => {
    var someLocalVar = o.someVar;

    return new Obj() { 
        Var1 = someLocalVar,
        Var2 = o.var2 
    }; 
}).ToArray();

14 votes

Cela force le queryable à être évalué.

0 votes

Cependant, dans cette circonstance, c'est correct, car il appelle ToArray() juste après de toute façon.

2 votes

Pas nécessairement - qui sait quelle est la taille de "o" ? il pourrait avoir 50 propriétés alors que nous n'en voulons que 2.

5voto

Mohsen Points 602

Utilisez cette surcharge de choix :

Obj[] myArray = objects.Select(new Func<Obj,Obj>( o =>
{
    var someLocalVar = o.someVar;

    return new Obj() 
    { 
       Var1 = someLocalVar,
       Var2 = o.var2 
    };
})).ToArray();

0 votes

Cela fonctionne pour moi, mais lorsqu'elle est utilisée avec Entity Framework, cette solution empêcherait-elle le dbcontext de charger d'abord toutes les lignes en mémoire, comme le ferait AsEnumerable() ?

2 votes

@parliament:Pour éviter de charger toutes les lignes en mémoire, vous devriez utiliser Expression<Func<Obj,Obj>> .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X