lambda函数中未知类型的引用属性

时间:2011-05-18 16:17:36

标签: asp.net vb.net linq telerik

我正在尝试创建一个通用函数来从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

提前感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:3)

And谓词之所以创建一个您未保存的新表达式。它不会修改现有的。您需要将每个returnPred.And行切换为

returnPred = returnPred.And(...