Obtención de ningún método genérico 'donde' en el tipo 'System.Linq.Queryable' es compatible con los argumentos y argumentos de tipo suministrados

.net c# expression-trees json

Pregunta

He estado escribiendo el árbol de expresiones para crear expresiones lambda dinámicamente.

Para empezar de a poco, estoy leyendo datos de un archivo JSON en un objeto de clase. Y tratando de construir la condición de dónde en dos condiciones.

string jsonnew = File.ReadAllText(@"C:\Users\nested_Json.txt");

var rootObject1 = JsonConvert.DeserializeObject<Citizen>(jsonnew);

IEnumerable<Citizen> enumerable = new[] { rootObject1 };

IQueryable<Citizen> queryableDataaa = enumerable.AsQueryable();

        ParameterExpression pe1 = Expression.Parameter(typeof(string), "rootobject");

        PropertyInfo field = typeof(Citizen).GetProperty("name");
        PropertyInfo field2 = typeof(Citizen).GetProperty("id");
        ParameterExpression targetExp = Expression.Parameter(typeof(Citizen), "rootobject");
        ParameterExpression valueExp = Expression.Parameter(typeof(string), "\"StrozeR\"");
        ParameterExpression valueExp2 = Expression.Parameter(typeof(Int32),"1765116");
        MemberExpression fieldExp = Expression.Property(targetExp, field);
        MemberExpression fieldExp2 = Expression.Property(targetExp, field2);
       Expression assignExp = Expression.Equal(fieldExp, valueExp);
       Expression assignExp2 = Expression.Equal(fieldExp2, valueExp2);

Expression predicateBody1 = Expression.AndAlso(assignExp, assignExp2);

MethodCallExpression whereCallExpression1 = Expression.Call(
            typeof(Queryable),
            "where",
            new Type[] { queryableDataaa.ElementType},
            queryableDataaa.Expression,
            Expression.Lambda<Func<string, bool>>(predicateBody1, new ParameterExpression[] { pe1 })); 

¿Puede alguien ayudarme a entender por qué me estoy poniendo

Ningún método genérico 'donde' en el tipo 'System.Linq.Queryable' es compatible con los argumentos y argumentos de tipo suministrados. No se deben proporcionar argumentos de tipo si el método no es genérico. error

Respuesta popular

Debes

  • Usa expresiones constantes para tus valores.
  • use un argumento con el tipo Citizen para la expresión de la cláusula where
  • encuentre el método Where (con mayúsculas) de IQueryable where es un método de extensión definido en System.Linq.Queryable , luego proporcione su tipo genérico
  • Invocar el método con los parámetros adecuados.

Aquí está el código corregido:

var targetExp = Expression.Parameter(typeof(Citizen), "rootobject");
var valueExp = Expression.Constant("\"StrozeR\"");
var valueExp2 = Expression.Constant(1765116);
var fieldExp = Expression.Property(targetExp, "name");
var fieldExp2 = Expression.Property(targetExp, "id");
var assignExp = Expression.Equal(fieldExp, valueExp);
var assignExp2 = Expression.Equal(fieldExp2, valueExp2);
var predicateBody1 = Expression.AndAlso(assignExp, assignExp2);

var queryableType = typeof(System.Linq.Queryable);
var whereMethod = queryableType.GetMethods()
       .First(m =>
       {
           var parameters = m.GetParameters().ToList();
           //Put more restriction here to ensure selecting the right overload                
           //the first overload that has 2 parameters
           return m.Name == "Where" && m.IsGenericMethodDefinition &&
                 parameters.Count == 2;
       });
var whereClause = Expression.Lambda<Func<Citizen, bool>>(predicateBody1, 
                  new ParameterExpression[] { targetExp });
var genericMethod = whereMethod.MakeGenericMethod(typeof(Citizen));
var newQuery = (IQueryable<Citizen>)genericMethod
              .Invoke(genericMethod, new object[] { queryableDataaa, whereClause });


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow