выполнить поиск LIKE с помощью Entity Framework и npgsql

Как я могу выполнить поиск LIKE с помощью Entity Framework 6 и npgsql?

Я попытался

<сильный>1. SQLMethods.Like

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

но я получил сообщение

LINQ to Entities не распознает метод 'Boolean Like(System.String, System.String)', и этот метод нельзя преобразовать в выражение хранилища.


2. метод расширения linq

Затем я попробовал метод расширения linq WhereLike из этого сообщения stackoverflow: https://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""


person Sven-Michael Stübe    schedule 29.07.2015    source источник
comment
Не уверен на 100% в этом, но я думаю, что для этого потребуется определенная поддержка в поставщике Npgsql EF6, которого в настоящее время нет. Не могли бы вы открыть вопрос об этом (github.com/npgsql/npgsql)? Хотя не уверен, что скоро мы к этому придем...   -  person Shay Rojansky    schedule 15.08.2015


Ответы (1)


Вы можете достичь той же цели, используя Regex.IsMatch().

Например. один из модульных тестов из репозитория Npgql:

[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));
person stack item    schedule 29.07.2015
comment
Тесты находятся в папке EntityFramework7. Я предполагаю, что эта функция поддерживается только в том случае, если вы используете EF7 или !? - person Sven-Michael Stübe; 30.07.2015
comment
Да, отображение регулярных выражений — это функция, реализованная только в (экспериментальном) провайдере EF7. - person Shay Rojansky; 15.08.2015