expression.call 值不能为空

expression.call value cannot be null

我正在尝试使用表达式树编写此 LINQ 查询代码:

Result = Result.Where(Function(Row) Convert.ToInt32(Row(2)) <= 10)

Result 声明为 Dim Result As IEnumerable(Of Object()).

到目前为止我有这个代码:

Dim queryiabledata As IQueryable(Of Object()) = Result.AsQueryable

Dim pe As ParameterExpression = Expression.Parameter(GetType(String), "Row(2)")
Dim left As expression = Expression.Call(pe, GetType(String).GetMethod("Convert.ToInt32", System.Type.EmptyTypes))
Dim right As Expression = Expression.Constant(10)
Dim e1 As Expression = Expression.LessThanOrEqual(left, right)

Dim predicatebody As Expression = e1
Dim wherecallexpression As MethodCallExpression = Expression.Call(
    GetType(Queryable), "Where", New Type() {queryiabledata.ElementType}, queryiabledata.Expression,
    Expression.Lambda(Of Func(Of Object(), Boolean))(predicatebody, New ParameterExpression() {pe}))

Result = queryiabledata.Provider.CreateQuery(Of Object())(wherecallexpression)

但是如果我运行查询,我会在 Expression.Call.

处收到 ArgumentNullException(值不能为 null。参数名称:方​​法)

我试图将 "Convert.ToInt32" 更改为 "Value",但我得到了同样的错误。

我该如何解决?

其他代码行是否正确以获得所需的结果?

我觉得这行很可疑:

GetType(String).GetMethod("Convert.ToInt32", System.Type.EmptyTypes)

GetType(String) returns 运行时类型 String。然后您尝试获取一个名为 "Convert.ToInt32" 的方法,该方法在字符串类型上不存在。我怀疑它正在返回 null,这是您的异常来源。

也许你需要使用这样的东西:

GetType(Convert).GetMethod("ToInt32", new Type() {GetType(Object)})

由于Convertclass的ToInt32方法有多个重载,你需要通过提供[=15=的数组来指定你想要哪个重载] 作为第二个参数。也就是说,你一句"give me the overload that takes an Object type as it's parameter".

我更习惯使用 C#,尽管我偶尔会 VB.NET。 VB.NET 中的反射非常丑陋。获取 Where 方法有点麻烦。这是代码:

shortFormlongForm 应该相同。

    Dim result As IEnumerable(Of Object()) = New List(Of Object())()
    Dim queryiabledata As IQueryable(Of Object()) = result.AsQueryable()
    Dim shortForm As Expression = queryiabledata.Where(Function(Row) Convert.ToInt32(Row(2)) <= 10).Expression

    Dim whereMethod = GetType(Queryable).GetMethods(BindingFlags.Public Or BindingFlags.Static).
        First(Function(m) m.Name = "Where").
        MakeGenericMethod(GetType(Object()))
    Dim convertMethod = GetType(System.Convert).GetMethod("ToInt32", New Type() {GetType(Object)})
    Dim rowParameter = Expression.Parameter(GetType(Object()), "Row")

    Dim longform As Expression =
        Expression.Call(
            whereMethod,
            queryiabledata.Expression,
            Expression.Lambda(
                Expression.LessThanOrEqual(
                    Expression.Call(
                            convertMethod,
                            Expression.ArrayAccess(
                                rowParameter,
                                Expression.Constant(2)
                            )
                        ),
                    Expression.Constant(10)
                ),
                rowParameter
            )
        )
    result = queryiabledata.Provider.CreateQuery(longform)