我正在尝试创建一个通用函数来从Telerik网格过滤器列表中构建Linq表达式。我想要保持清晰的动态Linq。因为我不知道我正在构建表达式的类型,所以我试图在lambda函数中使用反射来引用属性,但我的结果永远不会被过滤。调用my helper函数来获取属性值永远不会被调用,尽管它确实点击了“Add”行。将反射排成一行(例如下面的“GreaterThan”)并没有什么区别。这是我的代码:
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
提前感谢您提供的任何帮助。
答案 0 :(得分:3)
And
谓词之所以创建一个您未保存的新表达式。它不会修改现有的。您需要将每个returnPred.And
行切换为
returnPred = returnPred.And(...