この一連の記事をフォローしようとしています。パート 2 と 3 の間にいますが、いくつか問題があります。
私はいくつかの癖を投げたVB.Netでコードを書いています。
具体的には、式ツリーにアクセスすると、文字列比較が期待どおりに機能しません。
QueryProvider のこのメソッド (パート 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)
(パート 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
をに変換しようとすると、InvalidCastException がスローされます (それはStripQuotes(m.Arguments(1))
ですLambdaExpression
) ConstantExpression
。
VB から文字列比較を正しく処理するにはどうすればよいですか?