执行字符串比较器自定义LINQ提供程序在VB [英] Implementing string comparer in custom Linq Provider in 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 $一个InvalidCastException C $ C>(说这是一个
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屋!