#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:
Вы можете сделать, как показано ниже:
- Разделите текст поиска на слова
- сохраните логику выражения linq в переменной (за исключением части сопоставления строк).
- Добавьте выражение Содержит для каждого слова в поисковом запросе.
Код будет выглядеть следующим образом:
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. большое вам спасибо за ваше решение, но в связи с этим у меня возникает проблема. Я обновил скриншоты в рамках вопроса. Не могли бы вы, пожалуйста, помочь нам в решении этой проблемы?