свойство ссылки неизвестного типа в лямбда-функции - PullRequest
2 голосов
/ 18 мая 2011

Я пытаюсь создать универсальную функцию для построения выражения Linq из списка сеточных фильтров Telerik. Я пытаюсь держаться подальше от динамического Linq. Поскольку я не знаю тип, для которого я строю выражение, я пытаюсь использовать отражение в лямбда-функциях для ссылки на свойство, но мои результаты никогда не фильтруются. Вызов моей вспомогательной функции для получения значения свойства никогда не вызывается, хотя он попадает в строки «Добавить». Помещение отражения в линию (например, «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 Ответ

3 голосов
/ 18 мая 2011

Причина, по которой предикат And создает новое выражение, которое вы не сохраняете. Он не изменяет существующий на месте. Вам нужно переключить каждую returnPred.And линию на

returnPred = returnPred.And(...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...