0

How can I perform a LIKE search with entity framework 6 and npgsql?

I tried

1. SQLMethods.Like

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

but I got the message

LINQ to Entities does not recognize the method 'Boolean Like(System.String, System.String)' method, and this method cannot be translated into a store expression.


2. linq extension method

Then I tried the linq extension method WhereLike from this stackoverflow post: https://stackoverflow.com/a/27153779/1489968

It's working, but not for all cases, because it's cutting the search string into several pieces.

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

is transformed into two and-connected Contains calls, that are transformed into two LIKE expressions.

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

which means "All entities with the name containing 'EU' and '6'"

But I want the transformation to result in a query like the following one:

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

which means "All entities with the name containing 'EU' followed by a string, that contains '6'"

Community
  • 1
  • 1
Sven-Michael Stübe
  • 14,560
  • 4
  • 52
  • 103
  • Not 100% sure about this, but I think it would need some specific support in the Npgsql EF6 provider which is currently not there. Could you please open an issue about this (github.com/npgsql/npgsql)? Not sure we'll get around to this soon though... – Shay Rojansky Aug 15 '15 at 11:06

1 Answers1

0

You can achieve the same goal using Regex.IsMatch().

E.g. one of the unit tests from 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);
}

So I believe in your case it would look something like this:

var pattern = ".*" + Regex.Escape("EW") + ".*" + Regex.Escape("6") + ".*";
queryable.Where(t => Regex.IsMatch(t.Name, pattern));
stack item
  • 544
  • 4
  • 11