Поиск имен по каждому слову в строке поиска

#c# #asp.net #asp.net-mvc #entity-framework #linq

Вопрос:

Я пытаюсь построить поиск в своей ASP.NET Веб-сайт MVC. Например, я хочу вернуть товары, которые соответствуют товарам, имеющим совпадения по ключевым словам в строке поиска. В качестве примера у меня есть такие продукты, как,

  • СВЕТОДИОДНАЯ ЛЕНТА ПОСТОЯННОГО ТОКА 12 В RGB 5050 5 М
  • Комплект светодиодной ленты RGB 5050 длиной 5 метров с 24 клавишами ИК — пульта дистанционного управления
  • Светодиодные ленты освещают DC 12V 44 Клавиши ИК-пульта дистанционного управления RGB

В настоящее время, если я ищу «rgb-полосу«, я не получаю никаких результатов от поиска. Если я ищу «rgb-полосу«, мне нужно вернуть первые два продукта, в которых есть ключевые слова » rgb » и «полоса» из текста поиска. В рамках текущей функциональности, если я ищу «rgb«, он возвращает все вышеперечисленные 3 продукта. Мне нужно реализовать механизм, который будет искать продукты, содержащие каждое слово в названиях продуктов. Но я не уверен, как это сделать. Пожалуйста, может ли кто-нибудь помочь мне в этом? Спасибо.

Текущая функция поиска:

 public List<Product> SearchProducts(List<int> categoryIDs, string searchTerm, decimal? from, decimal? to, string sortby, int? pageNo, int recordSize, bool activeOnly, out int count, int? stockCheckCount = null)
{
    var context = DataContextHelper.GetNewContext();

    var products = context.Products
                          .Where(x => !x.IsDeleted amp;amp; (!activeOnly || x.IsActive) amp;amp; !x.Category.IsDeleted)
                          .AsQueryable();

    if (!string.IsNullOrEmpty(searchTerm))
    {
        products = context.ProductRecords
                          .Where(x => !x.IsDeleted amp;amp; x.Name.ToLower().Contains(searchTerm.ToLower()))
                          .Select(x => x.Product)
                          .Where(x => !x.IsDeleted amp;amp; (!activeOnly || x.IsActive) amp;amp; !x.Category.IsDeleted)
                          .AsQueryable();
    }

    if (categoryIDs != null amp;amp; categoryIDs.Count > 0)
    {
        products = products.Where(x => categoryIDs.Contains(x.CategoryID));
    }
}
 

На основе ответа @Rashik Hasnat,

У меня здесь проблема с доступом к атрибуту имени, потому что атрибут имени наследуется от модели ProductRecords, но атрибут выражения сопоставлен с моделью продуктов. Не могли бы вы помочь решить эту проблему? Спасибо.

Ответ №1:

Я бы предпочел использовать здесь регулярное выражение, но, к сожалению, есть ограничение на его использование в LINQ для сущностей. Поэтому вы можете использовать функции DBFUNCTION.Как():

 if (!string.IsNullOrEmpty(searchTerm))
{
    // Build the pattern for the Like() method
    var pattern = "%"   String.Join("%", searchTerm.Split(' '))   "%";

    products = context.ProductRecords
                      .Where(x => !x.IsDeleted amp;amp; DbFunctions.Like(x.Name, pattern))
                      .Select(x => x.Product)
                      .Where(x => !x.IsDeleted amp;amp; (!activeOnly || x.IsActive) amp;amp; !x.Category.IsDeleted)
                      .AsQueryable();
}
 

Ответ №2:

Вы можете сделать, как показано ниже:

  1. Разделите текст поиска на слова
  2. сохраните логику выражения linq в переменной (за исключением части сопоставления строк).
  3. Добавьте выражение Содержит для каждого слова в поисковом запросе.

Код будет выглядеть следующим образом:

         if (!string.IsNullOrEmpty(searchTerm))
        {
            //split each word of the search string
            var searchWordList = searchTerm.Split(" "); 

            var expression = context.ProductRecords
                .Where(x => !x.IsDeleted amp;amp; x.Name.ToLower().Contains(searchTerm.ToLower())).Select(x => x.Product)
                .Where(x => !x.IsDeleted amp;amp; (!activeOnly || x.IsActive) amp;amp; !x.Category.IsDeleted);

            foreach (var word in searchWordList)
            {
                // Add a condition for each word to be present
                expression = expression
                    .Where(x => x.Name.ToLower().Contains(word.ToLower())); 
            }

            products = expression
                .AsQueryable();
        }
 

Комментарии:

1. большое вам спасибо за ваше решение, но в связи с этим у меня возникает проблема. Я обновил скриншоты в рамках вопроса. Не могли бы вы, пожалуйста, помочь нам в решении этой проблемы?