使用表达式的 LINQ 动态方法调用
我正在尝试在扩展 BindingList(Of T) 的类中使用 LINQ 表达式来实现多列过滤。以下是相关代码:
Public Function GetFilterPredicate() As Func(Of T, Boolean)
Dim expressionList As List(Of Expression) = New List(Of Expression)
For Each item as FilterInfo in _FilterList
Dim fieldName As String = item.FieldName
Dim fieldOperator As String = item.FieldOp
Dim fieldValue As Object = item.FieldValue
Dim obj As ParameterExpression = Expression.Parameter(GetType(T), "obj")
Dim objProp As MemberExpression = Expression.PropertyOrField(obj, fieldName)
Dim filterValue As ConstantExpression = Expression.Constant(fieldValue, objProp.Type)
Dim methodName As String = If(fieldOperator = "=", "Equal", "NotEqual")
Dim comparisonExp As MethodCallExpression = Expression.Call( _
GetType(Expression),
methodName,
New Type() {objProp.Type, filterValue.Type},
objProp, filterValue)
expressionList.Add(comparisonExp)
Next
//
// combine the expressions in expressionList using Expression.AndAlso
//
// create lambda
//
Dim fn As Func(Of T, Boolean) = lambda.Compile
Return fn
End Function
其用途如下:
Dim source As IQueryable(Of T) = MyBase.Items.ToList.AsQueryable
MyBase.ClearItems()
Dim filterPredicate As Func(Of T, Boolean) = GetFilterPredicate()
For Each item As T In source.Where(filterPredicate)
MyBase.Items.Add(item)
Next
但是,Expression.Call 语句会引发异常。我不太清楚要提供的正确论据。现在,我在运行代码时收到此错误:
InvalidOperationException was unhandled:
No generic method 'Equal' on type 'System.Linq.Expressions.Expression' is
compatible with the supplied type arguments and arguments. No type arguments
should be provided if the method is non-generic.
感谢任何帮助,谢谢。
I'm trying to implement multicolumn filtering using LINQ expressions in a class that extends BindingList(Of T). Here is the relevant code:
Public Function GetFilterPredicate() As Func(Of T, Boolean)
Dim expressionList As List(Of Expression) = New List(Of Expression)
For Each item as FilterInfo in _FilterList
Dim fieldName As String = item.FieldName
Dim fieldOperator As String = item.FieldOp
Dim fieldValue As Object = item.FieldValue
Dim obj As ParameterExpression = Expression.Parameter(GetType(T), "obj")
Dim objProp As MemberExpression = Expression.PropertyOrField(obj, fieldName)
Dim filterValue As ConstantExpression = Expression.Constant(fieldValue, objProp.Type)
Dim methodName As String = If(fieldOperator = "=", "Equal", "NotEqual")
Dim comparisonExp As MethodCallExpression = Expression.Call( _
GetType(Expression),
methodName,
New Type() {objProp.Type, filterValue.Type},
objProp, filterValue)
expressionList.Add(comparisonExp)
Next
//
// combine the expressions in expressionList using Expression.AndAlso
//
// create lambda
//
Dim fn As Func(Of T, Boolean) = lambda.Compile
Return fn
End Function
This is intended to be used like so:
Dim source As IQueryable(Of T) = MyBase.Items.ToList.AsQueryable
MyBase.ClearItems()
Dim filterPredicate As Func(Of T, Boolean) = GetFilterPredicate()
For Each item As T In source.Where(filterPredicate)
MyBase.Items.Add(item)
Next
However, an exception is thrown at the Expression.Call statement. I can't quite figure out the right arguments to supply. As it is now, I am getting this error when I run the code:
InvalidOperationException was unhandled:
No generic method 'Equal' on type 'System.Linq.Expressions.Expression' is
compatible with the supplied type arguments and arguments. No type arguments
should be provided if the method is non-generic.
Any help is appreciated, thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您应该简单地生成一个不同的表达式树,而不是尝试使用反射来调用“Equal”或“NotEqual”。请原谅我糟糕的 VB.NET 语法,但可能是这样的:
Rather than trying to use reflection to call "Equal" or "NotEqual", you should simply produce a different expression tree. Pardon my poor VB.NET syntax, but something like this maybe: