2

I am using Dynamic Linq to execute a T-SQL where clause against LINQ. This works great except when trying to convert the LIKE statement which I have manually attempted to convert with a function that I have included at the end of the post. The code is not even close to being perfect, but I stopped programming this when I realized that I would get an error during testing. The code that executes essentially takes this:

"trx_no like '%3500%'"

And converts it to this:

"trx_no.Contains("3500")"

To execute this:

Dim x = y.Where("trx_no.Contains("3500")", Nothing)

The Error:

No applicable method 'Contains' exists in type 'Int32?'

The issue I think is that I need to convert the "trx_no" which is a Nullable(Of Int32) to a String, so after two days of research and book reading I figured that I would need to convert the string in a delegate function which I can not get to work.

I have also tried to use Cast like in this link here, however this fails with an error:

Expression of type 'Boolean' expected

My version looked like this:

Dim x = y.Where("DirectCast(trx_no, System.String) like '%35000%'", Nothing)

If I have not included enough code I am sorry I just did not want to make this to overwhelming. Any suggestions would be much appreciated. Thank You.

`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
DNapoleon
  • 41
  • 4

1 Answers1

2

I found that the predefinedTypes in the Dynamic Linq Library supported Convert, which I used to formulate the following:

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

This lead to an issue with converting Nullable(Of ) to a string if the propertyName above was a Nullable type. Editing the Dynamic.vb code in the Dynamic Linq Library for the ParseMemberAccess method allowed the conversion to work. Below is the edit made to the Select Case statement in that method:

            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
DNapoleon
  • 41
  • 4