.net - Linq SqlMethods.Like 失败

标签 .net linq-to-entities

我正在遵循提示 here ,尝试利用在枚举器被触发之前不会创建 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);
                }
            }

注释:db 是映射到 SQL Server 的实体。

最佳答案

我不知道如何使 Entity Framework 使用“真正的”LIKE 运算符,但可能的解决方法是用 StartsWithContains< 来表达 LIKE 表达式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")

等等...

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

这是一个示例实现,使用 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;
    }
}

以下是如何使用它:

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

我刚刚用一个简单的 EF 模型尝试过,它似乎工作得很好:)

关于.net - Linq SqlMethods.Like 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2584598/

相关文章:

c# - 删除foreach中的对象

c# - 先按大写字母排序

c# - 如何将 C# Select () 扩展委托(delegate)或表达式传递给存储库?

c# - 如何抽象 Linq 查询的选择列表中的字段?

.net - 如何自动更新野田时间数据库,多久更新一次?

c# - Entity Framework Fluent API 映射简单的一对多关系

c# - 是否有可能诱使此 WindowsIdentity 代码使用错误的用户?

c# - 如何将 .NET CommandArgument 用作非字符串对象?

c# - 在 C# 项目中定义输出路径的正确方法是什么

c# - 当查询仅因属性不同时,如何解决 LINQ to Entity 查询重复问题?