执行字符串比较器自定义LINQ提供程序在VB [英] Implementing string comparer in custom Linq Provider in VB

查看:142
本文介绍了执行字符串比较器自定义LINQ提供程序在VB的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图按照这一系列文章的。我是件2和3之间,但我有一些问题。

I'm attempting to follow this series of articles. I'm between parts 2 and 3 but am having some issues.

我写了code在VB.Net已抛出了几个怪癖。

I'm writing the code in VB.Net which has thrown a couple of quirks.

具体而言,参观前pression树时,字符串比较工作不正常。

Specifically, when visiting the expression tree, string comparisons aren't working as expected.

这个方法在QueryProvider(<一href="http://blogs.msdn.com/b/mattwar/archive/2007/07/31/linq-building-an-iqueryable-provider-part-ii.aspx"相对=nofollow>第2部分)

This method in the QueryProvider (Part 2)

Protected Overrides Function VisitMethodCall(m As MethodCallExpression) As Expression
    If m.Method.DeclaringType = GetType(Queryable) AndAlso m.Method.Name = "Where" Then
        sb.Append("SELECT * FROM (")
        Me.Visit(m.Arguments(0))
        sb.Append(") AS T WHERE ")
        Dim lambda As LambdaExpression = DirectCast(StripQuotes(m.Arguments(1)), LambdaExpression)
        Me.Visit(lambda.Body)
        Return m
    End If
    Throw New NotSupportedException(String.Format("The method '{0}' is not supported", m.Method.Name))
End Function

时抛出一个NotImplementedException字符串比较

Is throwing a NotImplementedException for String comparisons

m.Method.DeclaringType 的类型是 Microsoft.VisualBasic.CompilerServices.Operators m.Method.Name 是 CompareString 。它看起来像字符串相等的处理略有不同由VB和没有被拾起以正确的方式。

m.Method.DeclaringType is of type Microsoft.VisualBasic.CompilerServices.Operators and m.Method.Name is CompareString. It looks like the string equality is handled slightly differently by VB and isn't being picked up in the correct way.

我使用了一个 Query.Where(函数(X)x.Content_Type&LT;&gt;中)。测试

特别是,如果我调试调用 VisitBinary(b以BinaryEx pression)(也<一href="http://blogs.msdn.com/b/mattwar/archive/2007/07/31/linq-building-an-iqueryable-provider-part-ii.aspx"相对=nofollow>第2部分), B {(CompareString(x.Content_Type,,FALSE)!= 0)}

Specifically, if I debug the calls to VisitBinary(b As BinaryExpression) (Also Part 2), b is {(CompareString(x.Content_Type, "", False) != 0)}

这则试图访问 b.Left CompareString(x.Content_Type,,FALSE))这就是我们在 VisitMethodCall 落空孔。

This then attempts to visit b.Left (CompareString(x.Content_Type, "", False)) which is where we fall through the hole in VisitMethodCall.

如果我只是扩大了如果VisitMethodCall为

If I just expand the If in VisitMethodCall to be

    If (
            m.Method.DeclaringType = GetType(Queryable) AndAlso
            m.Method.Name = "Where"
        ) Or (
            m.Method.DeclaringType = GetType(Microsoft.VisualBasic.CompilerServices.Operators) AndAlso
            m.Method.Name = "CompareString") Then

它抛出的尝试转换的 StripQuotes(m.Arguments(1)) LambdaEx pression (说这是一个 ConstantEx pression

什么我需要做的,从VB正确处理字符串比较?

What do I need to do to handle string comparisons correctly from VB?

推荐答案

使用下面的类:

Imports System.Linq.Expressions

Public Class VbCompareReplacer
    Inherits ExpressionVisitor

    Public Overrides Function Visit(node As Expression) As Expression
        If Not TypeOf node Is BinaryExpression Then Return MyBase.Visit(node)

        Dim binaryExpression = DirectCast(node, BinaryExpression)

        If Not TypeOf binaryExpression.Left Is MethodCallExpression Then Return MyBase.Visit(node)

        Dim method = DirectCast(binaryExpression.Left, MethodCallExpression)

        If Not (method.Method.DeclaringType = GetType(Microsoft.VisualBasic.CompilerServices.Operators) AndAlso
            method.Method.Name = "CompareString") Then Return MyBase.Visit(node)

        Dim left = method.Arguments(0)
        Dim right = method.Arguments(1)

        Return If(binaryExpression.NodeType = ExpressionType.Equal,
                  Expression.Equal(left, right),
                  Expression.NotEqual(left, right))
    End Function
End Class

现在,如果你有从VB编译器的前pression,例如:

Now if you have an expression from the vb compiler, for example

Dim expressionFromVb As Expression(Of Func(Of String, Boolean)) = Function(x) x = "b"

其具有结构{(CompareString(X,b的,假)​​== 0)}使用

which has the structure {(CompareString(x, "b", False) == 0)} use

Dim newExpression = New VbCompareReplacer().Visit(expressionFromVb)

而不是 EX pressionFromVb ,其结构{X =>(X ==B)}。所有凌乱VB比较是由预期(IN-)相等比较代替。如果你把 newEx pression 成C#编写了LINQ提供程序,它现在应该正常工作。

instead of expressionFromVb which has the structure {x => (x == "b")}. All messy vb comparisons are replaced by the expected (in-)equality comparisons. If you put newExpression into your linq provider written for c#, it should work properly now.

这篇关于执行字符串比较器自定义LINQ提供程序在VB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆