我正在尝试创建一个泛型函数,以从 Telerik 网格过滤器列表构建 Linq 表达式。 我试图远离动态 Linq。 因为我不知道要为其构建表达式的类型,所以我尝试在 lambda 函数中使用反射来引用属性,但我的结果从未被过滤。 从不调用对我的帮助程序函数以获取属性值的调用,尽管它确实命中"Add"行。 将反射放在一起(例如下面的"大于")不会有什么区别。 这是我的代码:
Public Shared Function buildRadFilter(Of T)(ByVal filterExpression As List(Of GridFilterExpression)) As Expressions.Expression(Of Func(Of T, Boolean))
Dim returnPred = PredicateBuilder.True(Of T)()
For Each exp As GridFilterExpression In filterExpression
Dim iExp = exp
Dim doDefault = False
Select Case iExp.FilterFunction
Case "Contains"
returnPred.And(Function(x) DirectCast(propVal(x, iExp.FieldName), String).Contains(iExp.FieldValue))
Case "DoesNotContain"
returnPred.And(Function(x) Not DirectCast(propVal(x, iExp.FieldName), String).Contains(iExp.FieldValue))
Case "StartsWith"
returnPred.And(Function(x) DirectCast(propVal(x, iExp.FieldName), String).StartsWith(iExp.FieldValue))
Case "EndsWith"
returnPred.And(Function(x) DirectCast(propVal(x, iExp.FieldName), String).EndsWith(iExp.FieldValue))
Case "EqualTo"
returnPred.And(Function(x) propVal(x, iExp.FieldName) = iExp.FieldValue)
Case "NotEqualTo"
returnPred.And(Function(x) propVal(x, iExp.FieldName) <> iExp.FieldValue)
Case "GreaterThan"
'returnPred.And(Function(x) propVal(x, iExp.FieldName) > iExp.FieldValue)
returnPred.And(Function(x) x.GetType().GetProperty(iExp.FieldName).GetValue(x, Nothing))
Case "GreaterThanOrEqualTo"
returnPred.And(Function(x) propVal(x, iExp.FieldName) >= iExp.FieldValue)
Case "LessThan"
returnPred.And(Function(x) propVal(x, iExp.FieldName) < iExp.FieldValue)
Case "LessThanOrEqualTo"
returnPred.And(Function(x) propVal(x, iExp.FieldName) <= iExp.FieldValue)
Case "IsEmpty"
returnPred.And(Function(x) propVal(x, iExp.FieldName) = "")
Case "NotIsEmpty"
returnPred.And(Function(x) propVal(x, iExp.FieldName) <> "")
Case "IsNull"
returnPred.And(Function(x) propVal(x, iExp.FieldName) Is Nothing)
Case "NotIsNull"
returnPred.And(Function(x) propVal(x, iExp.FieldName) IsNot Nothing)
Case "Between"
Dim vals As String() = iExp.FieldValue.Split(" ")
If vals.Length > 1 Then
returnPred.And(Function(x) propVal(x, iExp.FieldName) >= vals(0) AndAlso propVal(x, iExp.FieldName) <= vals(1))
Else
doDefault = True
Exit Select
End If
Case "NotBetween"
Dim vals As String() = iExp.FieldValue.Split(" ")
If vals.Length > 1 Then
returnPred.And(Function(x) propVal(x, iExp.FieldName) < vals(0) OrElse propVal(x, iExp.FieldName) > vals(1))
Else
doDefault = True
Exit Select
End If
Case Else
doDefault = True
Exit Select
End Select
If doDefault Then
returnPred.And(Function(x) DirectCast(propVal(x, iExp.FieldName), String).StartsWith(iExp.FieldValue))
End If
Next
Return returnPred
End Function
'only works for scalar values
Public Shared Function propVal(ByRef obj As Object, ByVal name As String) As Object
Return obj.GetType().GetProperty(name).GetValue(obj, Nothing)
End Function
提前感谢您提供的任何帮助。
And
谓词的原因是创建一个您没有保存的新表达式。 它不会就地修改现有的。 您需要将每returnPred.And
行切换到
returnPred = returnPred.And(...