C# 没有通用方法';其中';关于类型';System.Linq.Queryable';与提供的类型参数和参数兼容

C# 没有通用方法';其中';关于类型';System.Linq.Queryable';与提供的类型参数和参数兼容,c#,.net,json,expression-trees,C#,.net,Json,Expression Trees,我一直在编写表达式树来动态创建lambda表达式 首先,我将JSON文件中的数据读取到类对象中。并尝试在两个条件上构建where条件 string jsonnew = File.ReadAllText(@"C:\Users\nested_Json.txt"); var rootObject1 = JsonConvert.DeserializeObject<Citizen>(jsonnew); IEnumerable<Citizen> enumerable = new[

我一直在编写表达式树来动态创建lambda表达式

首先,我将JSON文件中的数据读取到类对象中。并尝试在两个条件上构建where条件

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 })); 
string jsonnew=File.ReadAllText(@“C:\Users\nested_Json.txt”);
var rootObject1=JsonConvert.DeserializeObject(jsonnew);
IEnumerable enumerable=new[]{rootObject1};
IQueryable queryableDataaa=可枚举的.AsQueryable();
ParameterExpression pe1=Expression.Parameter(typeof(string),“rootobject”);
PropertyInfo字段=typeof(Citizen).GetProperty(“名称”);
PropertyInfo字段2=typeof(Citizen).GetProperty(“id”);
ParameterExpression targetExp=Expression.Parameter(typeof(Citizen),“rootobject”);
ParameterExpression valueExp=Expression.Parameter(typeof(string),“\”StrozeR\”;
ParameterExpression valueExp2=表达式参数(typeof(Int32),“1765116”);
MemberExpression fieldExp=Expression.Property(targetExp,字段);
MemberExpression fieldExp2=Expression.Property(targetExp,field2);
表达式assignExp=Expression.Equal(fieldExp,valueExp);
表达式assignExp2=表达式.Equal(fieldExp2,valueExp2);
Expression predicateBody1=Expression.AndAlso(assignExp,assignExp2);
MethodCallExpression,其中CallExpression1=Expression.Call(
类型(可查询),
“哪里”,
新类型[]{queryableDataaa.ElementType},
queryableDataaa.Expression,
表达式Lambda(predicateBody1,新参数Expression[]{pe1});
有人能帮我弄明白我为什么会这样吗

类型System.Linq.Queryable上的泛型方法“where”与提供的类型参数和参数不兼容。如果方法是非泛型的,则不应提供类型参数。错误

你必须

  • 对值使用常量表达式
  • 对整个where子句表达式使用一个类型为
    Citizen
    的参数
  • 查找
    IQueryable的
    Where
    (大写w)方法,其中是在
    System.Linq.Queryable
    中定义的扩展方法,然后提供它的泛型类型
  • 使用适当的参数调用该方法
以下是更正后的代码:

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 });
var targetExp=Expression.Parameter(typeof(Citizen),“rootobject”);
var valueExp=表达式常数(“\”StrozeR\”);
var valueExp2=表达式常数(1765116);
var fieldExp=Expression.Property(targetExp,“name”);
var fieldExp2=Expression.Property(targetExp,“id”);
var assignExp=表达式.Equal(fieldExp,valueExp);
var assignExp2=表达式.Equal(fieldExp2,valueExp2);
var predicateBody1=表达式.AndAlso(assignExp,assignExp2);
var queryableType=typeof(System.Linq.Queryable);
var whereMethod=queryableType.GetMethods()
.第一(m=>
{
var parameters=m.GetParameters().ToList();
//在此处设置更多限制,以确保选择正确的重载
//具有2个参数的第一个重载
返回m.Name==“Where”&&m.IsGenericMethodDefinition&&
参数。计数==2;
});
var whereClause=Expression.Lambda(predicateBody1,
新参数表达式[]{targetExp});
var genericMethod=whereMethod.MakeGenericMethod(typeof(Citizen));
var newQuery=(IQueryable)genericMethod
.Invoke(genericMethod,新对象[]{queryableDataaa,whereClause});

要想找到目标,请尝试以下方法:

var where = new Func<IQueryable<int>, Expression<Func<int, bool>>, IQueryable<int>>(Queryable.Where).Method;
其中myType是您的类型

var whereForMyType = where.GetGenericMethodDefinition().MakeGenericMethod(myType);