我尝试使用表达式树编码此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(Value不能为null。参数名:方法)。
我尝试将"Convert.ToInt32"
更改为"Value"
,但我遇到了同样的错误。
我该如何解决?
另一个代码行是否正确以获得所需的结果?
答案 0 :(得分:0)
这条线似乎对我很怀疑:
GetType(String).GetMethod("Convert.ToInt32", System.Type.EmptyTypes)
GetType(String)
返回运行时类型String。然后,您尝试获取一个名为&#34; Convert.ToInt32&#34;的方法。它不存在于字符串类型中。我怀疑是返回null,这是你的异常的来源。
也许你需要使用这样的东西:
GetType(Convert).GetMethod("ToInt32", new Type() {GetType(Object)})
由于ToInt32
类的Convert
方法存在多个重载,因此您需要通过提供Type
数组作为第二个参数来指定所需的重载。换句话说,你是一个谚语&#34;给我一个带有Object类型的重载作为它的参数&#34;。
答案 1 :(得分:0)
我更习惯于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)