【问题标题】:Getting No generic method 'where' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments在类型“System.Linq.Queryable”上没有通用方法“where”与提供的类型参数和参数兼容
【发布时间】:2017-07-04 15:56:59
【问题描述】:

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

从小处着手,我将 JSON 文件中的数据读取到 Class 对象中。并尝试在两个条件下构建 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 })); 

任何人都可以帮助我了解我为什么会得到

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

【问题讨论】:

    标签: c# .net json expression-trees


    【解决方案1】:

    你必须

    • 为您的值使用常量表达式
    • 对整个 where 子句表达式使用一个类型为 Citizen 的参数
    • 找到IQueryableWhere(大写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 });
    

    【讨论】:

      【解决方案2】:

      要获取 Where,请尝试以下操作:

      var where = new Func<IQueryable<int>, Expression<Func<int, bool>>, IQueryable<int>>(Queryable.Where).Method;
      

      如果您希望它具有运行时类型,请执行

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

      myType 是你的类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-24
        • 1970-01-01
        • 2018-09-07
        • 2021-07-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多