LINQ to SQL - 字段包含在已知字符串中

时间:2012-06-19 16:02:00

标签: asp.net linq linq-to-sql

我正在基于用户输入动态构建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的{​​{1}}。当我运行它时,我得到“二进制运算符Equal没有定义为类型'System.Nullable (SqlFunctions.CharIndex(right, left) == 0) 0 1[System.Int32]' and 'System.Int32'." Explicitly casting the int?`with as表达式似乎导致LINQ提前运行查询。

有一种简单的方法吗?


编辑:

to

这样可行,但它生成的SQL如下所示:

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)
    );
}

如果可以,我很乐意使用CharIndex。

1 个答案:

答案 0 :(得分:1)

您可以尝试使用int http://msdn.microsoft.com/en-us/library/bb292051.aspx

将第一部分转换为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 ?))
            );
        }