.net VB中自定义Linq提供程序中字符串比较器的实现
我正试图跟上。我介于第2部分和第3部分之间,但有一些问题 我正在用VB.Net编写代码,这带来了一些怪癖 具体地说,当访问表达式树时,字符串比较无法按预期工作 此方法位于QueryProvider()中 正在为字符串比较抛出NotImplementedException.net VB中自定义Linq提供程序中字符串比较器的实现,.net,vb.net,linq,provider,.net,Vb.net,Linq,Provider,我正试图跟上。我介于第2部分和第3部分之间,但有一些问题 我正在用VB.Net编写代码,这带来了一些怪癖 具体地说,当访问表达式树时,字符串比较无法按预期工作 此方法位于QueryProvider()中 正在为字符串比较抛出NotImplementedException m.Method.DeclaringType属于Microsoft.VisualBasic.CompilerServices.Operators类型,而m.Method.Name属于CompareString。看起来VB处理字符
m.Method.DeclaringType
属于Microsoft.VisualBasic.CompilerServices.Operators
类型,而m.Method.Name
属于CompareString
。看起来VB处理字符串相等的方式略有不同,并且没有以正确的方式获取
我正在使用查询。其中(function(x)x.Content\u Type“”)
进行测试
具体地说,如果我调试对VisitBinary(b作为二进制表达式)
(同样),b
是{(CompareString(x.Content\u Type,“,False)!=0)}
然后尝试访问b.Left
(CompareString(x.Content\u Type,”,False)
),这就是我们在VisitMethodCall
中遇到的漏洞
如果我只是在VisitMethodCall中将If扩展为
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))
转换为LambdaExpression
(表示它是ConstantExpression
)时,在
要从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编译器的表达式,例如
Dim expressionFromVb As Expression(Of Func(Of String, Boolean)) = Function(x) x = "b"
它的结构是{(CompareString(x,“b”,False)==0)}use
而不是具有结构{x=>(x==“b”)}的
expressionFromVb
。所有凌乱的vb比较都将替换为预期的(in-)相等比较。如果将newExpression
放入为c#编写的linq提供程序中,它现在应该可以正常工作。@DanielHilgarth tbh I'm(lambas可以用来代替anon func/delegate,但不必如此),但无论哪种方式,重点都是,这个QueryProvider应该能够遍历一个表达式树,它可以很好地包含lambda,并将其转换为一个查询字符串,以便在其他地方使用。+1这是一个非常优雅的解决方案。明天上班的时候我会把它转一转,看看进展如何,谢谢。
Dim expressionFromVb As Expression(Of Func(Of String, Boolean)) = Function(x) x = "b"
Dim newExpression = New VbCompareReplacer().Visit(expressionFromVb)