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)})
由于Convert
class的ToInt32
方法有多个重载,你需要通过提供[=15=的数组来指定你想要哪个重载] 作为第二个参数。也就是说,你一句"give me the overload that takes an Object type as it's parameter".
我更习惯使用 C#,尽管我偶尔会 VB.NET。 VB.NET 中的反射非常丑陋。获取 Where
方法有点麻烦。这是代码:
shortForm
和 longForm
应该相同。
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)
我正在尝试使用表达式树编写此 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
.
我试图将 "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)})
由于Convert
class的ToInt32
方法有多个重载,你需要通过提供[=15=的数组来指定你想要哪个重载] 作为第二个参数。也就是说,你一句"give me the overload that takes an Object type as it's parameter".
我更习惯使用 C#,尽管我偶尔会 VB.NET。 VB.NET 中的反射非常丑陋。获取 Where
方法有点麻烦。这是代码:
shortForm
和 longForm
应该相同。
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)