使用实体框架和npgsql执行LIKE搜索

时间:2015-07-29 11:20:59

标签: c# linq entity-framework postgresql npgsql

如何使用实体框架6和npgsql执行LIKE搜索?

我试过

1。 SQLMethods.Like

queryable.Where(entity => SqlMethods.Like(entity.Name, "%EW%6%"));

但我收到了消息

  

LINQ to Entities无法识别方法'Boolean Like(System.String,System.String)'方法,并且此方法无法转换为商店表达式。


2。 linq扩展方法

然后我尝试了这个stackoverflow帖子中的linq扩展方法WhereLikehttps://stackoverflow.com/a/27153779/1489968

它可以工作,但并非适用于所有情况,因为它会将搜索字符串切割成几个部分。

queryable.WhereLike(t => t.Name, "%EW%6%"));

转换为两个连接的Contains调用,转换为两个LIKE表达式。

SELECT ... 
WHERE ... AND 
("Extent1"."name" LIKE E'%EU%' AND "Extent1"."name" LIKE E'%6%')

表示“名称中包含'EU'和'6'的所有实体

但是我希望转换能够产生如下的查询:

SELECT ... 
WHERE ... AND
("Extent1"."name" LIKE E'%EW%6%')

表示“名称中包含'EU'的所有实体后跟一个字符串,其中包含'6'”

1 个答案:

答案 0 :(得分:0)

您可以使用Regex.IsMatch()实现相同的目标。

E.g。来自Npgql repository的单元测试之一:

[Fact]
public virtual void Regex_IsMatchOptionsNone()
{
    AssertQuery<Customer>(
        cs => cs.Where(c => Regex.IsMatch(c.CompanyName, "^A", RegexOptions.None)),
        entryCount: 4);
    Assert.Contains("WHERE \"c\".\"CompanyName\" ~ ('(?p)' || '^A')", Sql);
}

所以我相信你的情况会是这样的:

var pattern = ".*" + Regex.Escape("EW") + ".*" + Regex.Escape("6") + ".*";
queryable.Where(t => Regex.IsMatch(t.Name, pattern));