Как создать метод расширения, который Entity Framework может преобразовать в запрос SQL? - PullRequest
1 голос
/ 22 мая 2019

Я создаю простую функцию поиска на сайте.Функция поиска должна просто искать строку в различных свойствах списка объектов (IQueryable).

Объекты поступают из таблицы базы данных Oracle с использованием Entity Framework.

IQueryable<SupplierAddress> data = _dbContext.SupplierAddresses;

Далее мы фильтруем этот IQueryable с помощью searchString, которая была передана пользователем:

    data = data.Where(d =>                                
    d.Supplier.Name.ToUpper().Contains(searchTerm.Trim()) || 
    d.Supplier.NameCleaned.ToUpper().Contains(searchTerm.Trim()) || 
    d.Supplier.NameShort.ToUpper().Contains(searchTerm.Trim()) ||   
    d.Supplier.NameShortCleaned.ToUpper().Contains(searchTerm.Trim()) ||
    d.Town.ToUpper().Contains(searchTerm.Trim()) ||   
    d.Country.Name.ToUpper().Contains(searchTerm.Trim());

Теперь, как вы можете видеть, мы используем .Trim () для предотвращения ошибок (упомянутых в этом вопросе: ORA-01425: escape-символ должен быть символьной строкой длины 1 ).Из-за этой ошибки мы также не можем обрезать searchString перед выполнением фильтрации.

Я пытаюсь создать метод расширения, который выполняет как .Trim () searchString, так и .Contains,Этот метод расширения должен интерпретироваться Entity Framework и должен быть в состоянии преобразовать в правильный SQL-запрос EF.

Это мой текущий метод расширения:

public static class StringExtensions
{
    public static bool ContainsTrim(this string source, string toCheck)
    {
        return source.Contains(toCheck.Trim());
    }
}

Но при его использованиитаким образом, он не может быть успешно переведен в SQL-запрос.

    data = data.Where(d =>                                
    d.Supplier.Name.ToUpper().ContainsTrim(searchTerm) || 
    d.Supplier.NameCleaned.ToUpper().ContainsTrim(searchTerm) || 
    d.Supplier.NameShort.ToUpper().ContainsTrim(searchTerm) ||   
    d.Supplier.NameShortCleaned.ToUpper().ContainsTrim(searchTerm) ||
    d.Town.ToUpper().ContainsTrim(searchTerm) ||   
    d.Country.Name.ToUpper().ContainsTrim(searchTerm));

Мы получаем следующую ошибку:

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

Можно ли создать метод Extension, который выполняет как усечение, так и содержание, которое также может интерпретироваться EF?

Я также видел такие вещи, как хранение выражений в переменных (например, здесь: Могу ли я использовать метод расширения в Entity Framework SubQuery? ), который также может решить мою проблему, но выражениедолжен иметь возможность получать параметр (searchString).

Заранее спасибо за ваше время и помощь.

...