LINQ的SqlMethods.Like失败LINQ、SqlMethods、Like

2023-09-02 23:56:53 作者:╰’ 以后、拿命爱自己

我下面的提示这里,试图利用该语句在SQL不会被创建,直到枚举跳闸。但是我得到下面的code以下错误。我使用Linq2Entities,不LINQ2SQL。有没有办法做到这一点在Linq2entities?

I'm following the tips here, trying to leverage the statement that the sql doesn't get created until the enumerator is tripped. However I get the following error on the code below. I'm using Linq2Entities, not linq2sql. Is there a way to do this in Linq2entities?

法布尔赞(System.String,System.String)不能在客户端上使用;它仅适用于转换为SQL。

Method 'Boolean Like(System.String, System.String)' cannot be used on the client; it is only for translation to 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);
                }
            }

注:DB是一个实体映射到SQL Server

Notes: db is a entity mapping to a sql server.

推荐答案

我不知道你如何让实体框架使用的真正的LIKE操作员,而是一个可能的解决方法是将前preSS一个LIKE EX pression而言 StartsWith 包含的endsWith

I don't know how you can make Entity Framework use the "real" LIKE operator, but a possible workaround would be to express a LIKE expression in terms of StartsWith, Contains and 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")

等等...

And so on...

请注意,这是不完全等同于SQL中使用这样的:例如 LIKE'%ABC%BCD%将导致包含(ABC)及&安培;包含(BCD)。这将匹配ABCD,即使原来的LIKE条件不会。但是对于大多数情况下,它应该足够好。

Note that it isn't exactly equivalent to using LIKE in SQL : for instance LIKE '%abc%bcd%' would result in Contains("abc") && Contains("bcd"). This would match "abcd" even though the original LIKE condition wouldn't. But for most cases, it should be good enough.

下面是一个简单的实现,使用 predicateBuilder 和 LinqKit 建立前pressions根据LIKE模式:

Here's a sample implementation, using PredicateBuilder and LinqKit to build expressions based on a LIKE pattern :

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

和这里的如何,你可以使用它:

And here's how you could use it :

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

我只是想用一个简单的EF模型,它似乎做工精细:)

I just tried it with a simple EF model, and it seems to work fine :)