【问题标题】:Linq to Entities (EF 4.1): How to do a SQL LIKE with a wildcard in the middle ( '%term%term%')?Linq to Entities (EF 4.1):如何在中间使用通配符 ('%term%term%') 执行 SQL LIKE?
【发布时间】:2011-10-07 15:17:27
【问题描述】:

我要搜索这个:

Post Cereal

然后得到这个:

Post Honey Nut Cereal

通配符将是空格。

我知道我可以执行 SPLIT 和一系列 AND 和 Contains() 并将每个术语转换为 Linq 表达式作为规范对象,但是没有办法在发送到 SQL 的术语中遵守通配符吗?我查看了 Linq to SQL 中的 SQL 函数,但我不确定 Linq to Entities 中的 SQL 函数。

我想做这样的事情:

term = '%' + term.Replace(' ', '%') + '%';
db.table.where( p => System.Data.Objects.SqlClient.SqlFunctions
                     .SqlMethods.Like(p.fieldname, term) );

有什么建议吗?

【问题讨论】:

    标签: c# sql-server-2005 linq-to-entities entity-framework-4.1


    【解决方案1】:

    我相信你可以使用SqlFunctions.PatIndex:

    dt.Table.Where(p => SqlFunctions.PatIndex(term, p.fieldname) > 0);
    

    SqlFunctions.PatIndex 的行为与SQL LIKE 运算符相同。它支持所有标准通配符,包括:

    • % 零个或多个字符的任意字符串。
    • _(下划线)任何单个字符。
    • [ ] 指定范围 ([a-f]) 或集合 ([abcdef]) 内的任何单个字符。
    • [^] 任何不在指定范围 ([^a-f]) 或集合 ([^abcdef]) 内的单个字符。

    当 SqlMethods.Like 不可用时,SqlFunctions.PatIndex 通常可用(包括在 MVC 控制器中)

    【讨论】:

    • 这值得更多的赞成票。这对我来说非常有效,没有太多复杂性。
    • 博士。 Zim 是对的,几个小时以来一直在寻找解决方案,这是迄今为止我找到的最简单的解决方案。
    • 我在 .NET 中直接在 TSQL 中尝试过,但对我来说都没有。使用 EF 5、.NET 4.5 和 VS 2012
    • SqlFunctions.PatIndex 在 EF 4.0 中不受支持 - 我得到一个不受支持的异常。
    【解决方案2】:

    绕过 LINQ 并使用实体 SQL 过滤器可能更容易:

    var query - db.table.Where("TRIM(fieldname) LIKE @pattern");
    query.Parameters.Add(new ObjectParameter("pattern", term)); // term == "%what%ever%"
    

    query 的类型实现了IQueryable<TEntity>,因此您可以应用更多的 LINQ 运算符。

    【讨论】:

    • 我正在 LINQPad 中尝试此操作,但出现此异常:EntitySqlException: 'BusinessName' could not be resolved in the current scope or context. Make sure that all referenced variables are in scope, that required schemas are loaded, and that namespaces are referenced correctly. 其中“BusinessName”是我要过滤的列。无法弄清楚如何克服这一点。
    • @adrift 您需要使用上下文信息设置 LINQPad,我几乎不使用它,所以无济于事(IIRC 我只是引用了带有上下文和实体类型的程序集)。
    • 使用实体 SQL 确实是唯一的方法 - L2E 不支持这种类型的通配符搜索。要解决您的问题,请尝试使用it.BusinessName。 ESQL 中的列必须加前缀,it 是默认前缀 - here 是查询的完整示例。
    【解决方案3】:

    只是为了澄清 Ladislav 关于it.BusinessName 的评论。我认为他指的是在字段名称前加上.it。只要您在 where 子句中的字段名称前加上 it.,上述解决方案就可以工作。在我的情况下,我也不需要 TRIM() 。

    var query - db.table.Where("it.fieldname LIKE @pattern");
    query.Parameters.Add(new ObjectParameter("pattern", term)); // term == "%what%ever%"
    

    它在 Oracle 数据库上完美运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-04
      • 2010-11-01
      • 2019-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多