Динамический Linq с использованием объектов данных.Как преобразовать Int32 в String с целью вызова String.Contains () - PullRequest
2 голосов
/ 02 ноября 2011

Я использую Dynamic Linq для выполнения предложения T-SQL where против LINQ.Это прекрасно работает, кроме случаев, когда я пытаюсь преобразовать оператор LIKE, который я пытался преобразовать вручную, с помощью функции, которую я включил в конце поста.Код даже близко не идеален, но я перестал программировать это, когда понял, что во время тестирования я получу ошибку.Код, который выполняется по существу, принимает это:

"trx_no like '% 3500%'"

и преобразует его в следующее:

"trx_no.Contains (" 3500 ")"

Чтобы выполнить это:

Dim x = y.Where ("trx_no.Contains (" 3500 ")",Ничего)

Ошибка:

Нет применимого метода «Содержит» в типе «Int32?»

Проблема, которую я считаю, заключается в том, что мне нужно преобразовать «trx_no», который является Nullable (Of Int32), в строку, поэтому после двух дней исследований и чтения книг я решил, что мне нужно будет преобразовать строку в функцию делегата.который я не могу заставить работать.

Я также пытался использовать Cast, как в этой ссылке здесь , однако это не удается с ошибкой:

Ожидается выражение типа 'Boolean'

Моя версия выглядела так:

Dim x = y.Where ("DirectCast (trx_no, System.Строка) как '% 35000%' ", ничего)

Если я не включил достаточно кода, извините, я просто не хотел, чтобы это было подавляющим.Любые предложения будут высоко ценится.Спасибо.

`Private Function replaceLike(ByVal str As String) As String
    Dim rtn As String = ""
    If str.ToUpper.Contains(" LIKE '") Then
        Dim firstQuote As Int32 = str.ToUpper.IndexOf(" LIKE '") + 6
        If str.ToUpper.Chars(firstQuote + 1) = Chr(37) Then
            'If the character after the first single quote is a %, this is a Contains or EndsWith
            Dim secondQuote As Int32 = str.ToUpper.IndexOf("'", firstQuote + 1)
            If str.ToUpper.Chars(secondQuote - 1) = Chr(37) Then
                'Handles '%%', '%value%', '%'
                'Found % before the last quote, this is a Contains or has the value of '%'.
                Dim val = ""
                'See if the value is empty so that we can extract the value
                Select Case (secondQuote - 1) - (firstQuote + 1)
                    Case 0
                        'Has no value don't add
                    Case 1
                        'Has no value don't add
                    Case Else
                        val = str.Substring(firstQuote + 2, ((secondQuote - 2) - firstQuote - 1))
                End Select
                str = str.Remove(firstQuote - 6, secondQuote - (firstQuote - 7))
                str = str.Insert(firstQuote - 6, ".Contains(""" & val & """) ")
            Else
                'Handles '%value'
                'Did not find another % before the last quote, this is a EndsWith
                Dim val = str.Substring(firstQuote + 2, ((secondQuote - 2) - firstQuote - 1))
                str = str.Remove(firstQuote - 6, secondQuote - (firstQuote - 7))
                str = str.Insert(firstQuote - 6, ".EndsWith(""" & val & """) ")
            End If

        Else
            'Else the character after the first single quote is not a %, this is a StartWith or is Empty
            Dim secondQuote As Int32 = str.ToUpper.IndexOf("'", firstQuote + 1)
            If str.ToUpper.Chars(secondQuote - 1) = Chr(37) Then
                'Handles 'value%'
                'Found a % before the last quote, this is a StartsWith
                Dim val = str.Substring(firstQuote + 2, ((secondQuote - 2) - firstQuote - 1))
                str = str.Remove(firstQuote - 6, secondQuote - (firstQuote - 7))
                str = str.Insert(firstQuote - 6, ".StartsWith(""" & val & """) ")
            Else
                'Handles ''
                'Found no %
                str = str.Remove(firstQuote - 6, secondQuote - (firstQuote - 7))
                str = str.Insert(firstQuote - 6, ".Contains("""") ")
            End If
        End If
        rtn = replaceLike(str)
    Else
        Return str
    End If

    Return rtn
End Function

1 Ответ

2 голосов
/ 03 ноября 2011

Я обнаружил, что предопределенные типы в динамической библиотеке Linq поддерживают преобразование, которое я использовал для формулировки следующего:

"Convert.ToString(" & propertyName & ").Contains(""" & val & """)"

Это приводит к проблеме с преобразованием Nullable (Of) в строку, если свойство propertyName выше имеет тип Nullable. Редактирование кода Dynamic.vb в динамической библиотеке Linq для метода ParseMemberAccess позволило преобразованию работать. Ниже приведено редактирование оператора Select Case в этом методе:

            Select Case FindMethod(type, id, instance Is Nothing, args, mb)
                Case 0
                    Throw ParseError(errorPos, Res.NoApplicableMethod, id, GetTypeName(type))
                Case 1
                    Dim method = DirectCast(mb, MethodInfo)
                    If (Not IsPredefinedType(method.DeclaringType)) Then
                        Throw ParseError(errorPos, Res.MethodsAreInaccessible, GetTypeName(method.DeclaringType))
                    End If
                    If method.ReturnType.Equals(GetType(Void)) Then
                        Throw ParseError(errorPos, Res.MethodIsVoid, id, GetTypeName(method.DeclaringType))
                    End If
                    Dim newargs As Expression() = args
                    For Each a As Expression In args
                        If a.Type.IsGenericType AndAlso a.Type.GetGenericTypeDefinition = GetType(Nullable(Of )) Then
                            newargs(Array.IndexOf(args, a)) = System.Linq.Expressions.Expression.Convert(a, GetType(Object))
                        Else
                            newargs(Array.IndexOf(args, a)) = a
                        End If
                    Next
                    Return Expression.Call(instance, DirectCast(method, MethodInfo), newargs)
                Case Else
                    Throw ParseError(errorPos, Res.AmbiguousMethodInvocation, id, GetTypeName(type))
            End Select
...