values not multiple framework c# entity-framework linq-to-entities predicate linqkit

c# - not - Cómo usar predicados en LINQ to Entities para objetos de Entity Framework



linq where list contains (2)

Los métodos utilizados en Linq to Entities deben ser cartografiados por el proveedor de Linq para que funcionen. Como el proveedor de Linq, EF en su caso, no pudo asignar su predicado a un método interno, arrojó un error.

Para los escenarios LINQ, las consultas en el marco de Entity Framework implican el mapeo de ciertos métodos CLR a métodos en la fuente de datos subyacente a través de funciones canónicas. Cualquier llamada de método en una consulta LINQ a Entidades que no esté asignada explícitamente a una función canónica dará como resultado una excepción en tiempo de ejecución de excepción NotSupportedException lanzada

Fuente: Método CLR para el mapeo de funciones canónicas ( http://msdn.microsoft.com/en-us/library/bb738681.aspx )

Puede tratar de tomar esos métodos que están mapeados y encadenarlos en su expresión Linq, o utilizar un procedimiento almacenado. Pero hasta que EF sea compatible con todo el CLR, te quedarás con la necesidad de encontrar una solución alternativa.

En el lado positivo, cada lanzamiento parece agregar un poco más a la lista canónica.

Merece la pena leerlo como posible solución alternativa : http://msdn.microsoft.com/en-us/library/dd456857.aspx

Estoy usando LINQ to Entities para objetos de Entity Framework en mi capa de acceso a datos.

Mi objetivo es filtrar todo lo que pueda de la base de datos, sin aplicar la lógica de filtrado a los resultados en la memoria.

Para ese propósito Business Logic Layer pasa un predicado a Data Access Layer.

quiero decir

Func<MyEntity, bool>

Entonces, si uso este predicado directamente, como

public IQueryable<MyEntity> GetAllMatchedEntities(Func<MyEntity, Boolean> isMatched) { return qry = _Context.MyEntities.Where(x => isMatched(x)); }

Estoy recibiendo la excepción

[System.NotSupportedException] --- {"LINQ to Entities no admite el tipo de nodo de expresión LINQ ''Invoke''."}

La solución en esa pregunta sugiere utilizar el método AsExpandable () de la biblioteca LINQKit .

Pero de nuevo, usando

public IQueryable<MyEntity> GetAllMatchedEntities(Func<MyEntity, Boolean> isMatched) { return qry = _Context.MyEntities.AsExpandable().Where(x => isMatched(x)); }

Estoy recibiendo la excepción

No se puede convertir el objeto del tipo ''System.Linq.Expressions.FieldExpression'' para escribir ''System.Linq.Expressions.LambdaExpression''

¿Hay alguna manera de utilizar el predicado en la consulta de LINQ a Entidades para los objetos del Marco de la Entidad, para que se lo transforme correctamente en una declaración SQL?

Gracias.


No necesita LinqKit para hacer esto. Solo recuerda usar

Expression<Func<MyEntity, bool>>

en lugar de

Func<MyEntity, bool>

Algo como esto:

public IQueryable<MyEntity> GetAllMatchedEntities(Expression<Func<MyEntity, Boolean>> predicate) { return _Context.MyEntities.Where(predicate); }

Debe usar Expression porque Linq to Entities necesita traducir su lambda a SQL.

Cuando utiliza Func, su lambda se compila en IL, pero cuando usa Expression, es un árbol de expresiones que Linq to Entities puede trasversar y convertir.

Esto funciona con expresiones que Linq to Entities entiende.

Si sigue fallando, su expresión hace algo que Linq to Entities no puede traducir a SQL. En ese caso, no creo que LinqKit ayude.

Editar:

No se necesita conversión Simplemente defina el método GetAllMatchedEntities con un parámetro Expression y úselo de la misma manera que lo haría con un parámetro Func. El compilador hace el resto.

Hay tres formas de usar GetAllMatchedEntities.

1) Con una expresión lambda en línea:

this.GetAllMatchedEntities(x => x.Age > 18)

2) Define tu Expresión como un campo (también puede ser una variable)

private readonly Expression<Func<MyEntity, bool>> IsMatch = x => x.Age > 18; ...then use it this.GetAllMatchedEntities(IsMatch)

3) Puedes crear tu expresión manualmente. El tamaño es más código y te pierdes los controles en tiempo de compilación.

public Expression<Func<MyEntity, bool>> IsMatchedExpression() { var parameterExpression = Expression.Parameter(typeof (MyEntity)); var propertyOrField = Expression.PropertyOrField(parameterExpression, "Age"); var binaryExpression = Expression.GreaterThan(propertyOrField, Expression.Constant(18)); return Expression.Lambda<Func<MyEntity, bool>>(binaryExpression, parameterExpression); }