3

ユーザー入力に基づいて動的にLINQクエリを作成しており、ユーザーが文字列strとフィールドfooに基づいてレコードrを検索している場合(str.Contains(r.foo))を処理したいと思います。さて、その逆(r.foo.Contains(str))は単純ですが、LINQはそれを逆に行うことについて私に悲しみを与えています。

これが私がこれまでに持っているものです:

private Expression SqlNotIn(Expression left, Expression right)
{
    return Expression.Equal(
        Expression.Call(
            null,
            typeof(SqlFunctions).GetMethod("CharIndex", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(string), typeof(string) }, null),
            new[] { right, left }
        ),
        Expression.Constant(0)
    );
}

Expression leftこれは、プロパティアクセサである、、Expression rightおよび検索する文字列の定数である、を取り、Expression(本質的に)を表すを返すことになってい(SqlFunctions.CharIndex(right, left) == 0)ます。これを実行すると、「バイナリ演算子Equalは型'System.Nullable 1[System.Int32]' and 'System.Int32'." Explicitly casting the0 toint?`に対して定義されていません。as式を使用すると、LINQがクエリを早期に実行するように見えます。

これを行う簡単な方法はありますか?


編集:

private Expression SqlNotIn(Expression left, Expression right)
{
    return Expression.Equal(
        Expression.Call(
            right,
            typeof(string).GetMethod("IndexOf", new[] { typeof(string) }),
            new[] { left }
        ),
        Expression.Constant(-1)
    );
}

これは機能しますが、生成されるSQLは次のようになります。

(CASE 
    WHEN DATALENGTH([t0].[Destination]) = 0 THEN 0
    ELSE CHARINDEX([t0].[Destination], @p0) - 1
 END) = @p1

できればCharIndexを使用できれば幸いです。

4

1 に答える 1

1

http://msdn.microsoft.com/en-us/library/bb292051.aspxを使用して、最初の部分をにint、または2番目の部分をに変換してみることができます。int?Expression.Convert

例えば。テストされていません。

private Expression SqlNotIn(Expression left, Expression right) {
            return Expression.Equal(
                Expression.Convert(Expression.Call(
                    null,
                    typeof(SqlFunctions).GetMethod("CharIndex", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(string), typeof(string) }, null),
                    new[] { right, left }
                ), typeof(int)),
                Expression.Constant(-1)
            );
        }

ちなみに、string inputValue2番目のパラメータとしてを使用して、Expression.Constant(inputValue)

編集

public static Expression SqlNotIn(Expression left, string right) {
            var method = typeof(string).GetMethod("IndexOf",
                new[] { typeof(string)});

            var call = Expression.Call(Expression.Constant(right), method, new []{left});

            var result =  Expression.Equal(call, Expression.Constant(0));
            return result;
        }

編集2:

private Expression SqlNotIn2(Expression left, Expression right) {
            return Expression.Equal(
                Expression.Call(
                    null,
                    typeof(SqlFunctions).GetMethod("PatIndex", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(string), typeof(string) }, null),
                    new[] { right, left }
                ),
                Expression.Convert(Expression.Constant(0), typeof(int ?))
            );
        }
于 2012-06-19T16:43:04.080 に答える