Linq SqlMethods.Like失败了

Rus*_*een 7 .net linq-to-entities

我正在遵循这里的提示,试图利用在枚举器被触发之前不会创建sql的语句.但是,我在下面的代码中收到以下错误.我正在使用Linq2Entities,而不是linq2sql.有没有办法在Linq2entities中执行此操作?

方法'Boolean Like(System.String,System.String)'不能在客户端上使用; 它仅用于转换为SQL.

            query = db.MyTables.Where(x => astringvar.Contains(x.Field1));

            if (!String.IsNullOrEmpty(typeFilter))
            {
                if (typeFilter.Contains('*'))
                {
                    typeFilter = typeFilter.Replace('*', '%');
                    query = query.Where(x=> SqlMethods.Like(x.Type, typeFilter));
                }
                else
                {
                    query  = query.Where(x => x.Type == typeFilter);
                }
            }
Run Code Online (Sandbox Code Playgroud)

注意:db是映射到sql server的实体.

Tho*_*que 11

我不知道如何让Entity Framework使用"真正的"LIKE运算符,但是一个可能的解决方法是表达一个LIKE表达式StartsWith,Contains并且EndsWith

例如 :

LIKE 'a%' => StartsWith("a")
LIKE '%a' => EndsWith("a")
LIKE '%a%' => Contains("a")
LIKE 'a%b' => StartsWith("a") && EndsWith("b")
LIKE 'a%b%' => StartsWith("a") && Contains("b")
Run Code Online (Sandbox Code Playgroud)

等等...

请注意,它并不完全等同于在SQL中使用LIKE:例如LIKE '%abc%bcd%'会导致Contains("abc") && Contains("bcd").这将匹配"abcd",即使原始的LIKE条件不会.但对大多数情况来说,它应该足够好了.

这是一个示例实现,使用PredicateBuilderLinqKit构建基于LIKE模式的表达式:

public static class ExpressionHelper
{
    public static Expression<Func<T, bool>> StringLike<T>(Expression<Func<T, string>> selector, string pattern)
    {
        var predicate = PredicateBuilder.True<T>();
        var parts = pattern.Split('%');
        if (parts.Length == 1) // not '%' sign
        {
            predicate = predicate.And(s => selector.Compile()(s) == pattern);
        }
        else
        {
            for (int i = 0; i < parts.Length; i++)
            {
                string p = parts[i];
                if (p.Length > 0)
                {
                    if (i == 0)
                    {
                        predicate = predicate.And(s => selector.Compile()(s).StartsWith(p));
                    }
                    else if (i == parts.Length - 1)
                    {
                        predicate = predicate.And(s => selector.Compile()(s).EndsWith(p));
                    }
                    else
                    {
                        predicate = predicate.And(s => selector.Compile()(s).Contains(p));
                    }
                }
            }
        }
        return predicate;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是你如何使用它:

var expr = ExpressionHelper.StringLike<YourClass>(x => x.Type, typeFilter);
query = query.AsExpandable().Where(expr.Compile());
Run Code Online (Sandbox Code Playgroud)

我只是尝试了一个简单的EF模型,它似乎工作正常:)


Nix*_*Nix 4

你可以执行 ESQL 并执行如下所示的操作。

     db.MyTables.Where("it.Type like '" + typeFilter + "'").ToList();
Run Code Online (Sandbox Code Playgroud)