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)1[System.Int32]' and 'System.Int32'." Explicitly casting the当我运行它时,我得到“没有为类型‘System.Nullable 0 int?’定义二进制运算符 Equal to,带有 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.aspxint将第一部分转换为,或将第二部分转换为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 inputValue用作第二个参数,并将其与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 回答