【发布时间】:2012-08-25 01:29:28
【问题描述】:
我正在尝试关注this series of articles。我在第 2 部分和第 3 部分之间,但遇到了一些问题。
我正在用 VB.Net 编写代码,这引发了一些怪癖。
具体来说,当访问表达式树时,字符串比较没有按预期工作。
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
m.Method.DeclaringType 是 Microsoft.VisualBasic.CompilerServices.Operators 类型,m.Method.Name 是 CompareString。看起来 VB 对字符串相等的处理方式略有不同,并且没有以正确的方式进行处理。
我正在使用Query.Where(function(x) x.Content_Type <> "") 进行测试。
具体来说,如果我调试对VisitBinary(b As BinaryExpression)(也称为Part 2)的调用,b 就是{(CompareString(x.Content_Type, "", False) != 0)}
然后它会尝试访问b.Left (CompareString(x.Content_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 时抛出 InvalidCastException(说它是 ConstantExpression)
我需要做什么才能在 VB 中正确处理字符串比较?
【问题讨论】:
-
@DanielHilgarth tbh 我是not convinced you're correct (lambas 可以用来代替匿名函数/代表,但不是必须的)但无论哪种方式,这个 QueryProvider 应该能够遍历一个很可能包含 lambdas 的表达式树并将其转换为查询字符串以在其他地方使用。