Al usar EntityFramework , aparece el error " A lambda expression with a statement body cannot be converted to an expression tree
" al intentar compilar el siguiente código:
Obj[] myArray = objects.Select(o =>
{
var someLocalVar = o.someVar;
return new Obj() {
Var1 = someLocalVar,
Var2 = o.var2 };
}).ToArray();
No sé qué significa el error y, sobre todo, cómo solucionarlo. ¿Alguna ayuda?
c#
linq
entity-framework
linq-to-entities
pistacho
fuente
fuente
Respuestas:
¿Es
objects
un contexto de base de datos Linq-to-SQL? En cuyo caso, solo puede usar expresiones simples a la derecha del operador =>. La razón es que estas expresiones no se ejecutan, sino que se convierten a SQL para ejecutarse en la base de datos. Prueba estofuente
Puede usar el cuerpo de la declaración en la expresión lamba para colecciones IEnumerable . prueba este:
Aviso:
piense detenidamente al usar este método, porque de esta manera, tendrá todos los resultados de la consulta en la memoria, que pueden tener efectos secundarios no deseados en el resto de su código.
fuente
AsEnumerable()
máscaras mi problema desaparece!Significa que no puede usar expresiones lambda con un "cuerpo de enunciado" (es decir, expresiones lambda que usan llaves) en lugares donde la expresión lambda necesita convertirse en un árbol de expresión (que es el caso cuando se usa linq2sql) .
fuente
Sin saber más sobre lo que está haciendo (Linq2Objects, Linq2Entities, Linq2Sql?), Esto debería hacer que funcione:
fuente
.AsEnumerable()
Use esta sobrecarga de select:
fuente
Expression<Func<Obj,Obj>>
.El objeto de retorno LINQ to SQL estaba implementando la
IQueryable
interfaz. Entonces, para elSelect
parámetro de predicado de método, solo debe proporcionar una sola expresión lambda sin cuerpo.Esto se debe a que el código LINQ for SQL no se ejecuta dentro del programa en lugar de en el lado remoto, como el servidor SQL u otros. Este tipo de ejecución de carga diferida se logró mediante la implementación de IQueryable donde su delegado esperado se está envolviendo en la clase de tipo Expresión como se muestra a continuación.
El árbol de expresión no admite la expresión lambda con cuerpo y solo admite la expresión lambda de una sola línea como
var id = cols.Select( col => col.id );
Entonces, si intentas, el siguiente código no funcionará.
Lo siguiente funcionará según lo esperado.
fuente
Significa que una expresión Lambda de tipo
TDelegate
que contiene un([parameters]) => { some code };
no se puede convertir en unExpression<TDelegate>
. Es la reglaSimplifica tu consulta. El que proporcionó puede reescribirse como sigue y compilará:
fuente
Es
Arr
un tipo base deObj
? ¿Existe la clase Obj? Su código funcionaría solo si Arr es un tipo base de Obj. Puedes probar esto en su lugar:fuente
Para su caso específico, el cuerpo es para crear una variable, y cambiar a
IEnumerable
forzará a que todas las operaciones se procesen en el lado del cliente, propongo la siguiente solución.Editar: Cambiar el nombre de la Convención de codificación C #
fuente