У меня было следующее LinqExpression:
var results = _localDatabase.Table<ArticleData>().Where(article =>
article.ArticleName!.ToLower().Contains(searchQuery.ToLower());
Недостаток этого решения заключался в том, что искомый текст должен был быть частью названия статьи. Но иногда пользователи вводят только части слов (название статьи — Spider-Man: Across the Spider-Verse
, а пользователи ищут man
и verse
). Поэтому я разбил поисковый запрос на отдельные части:
string[] splitQuerry = searchQuery.Split(' ');
И попробовал поискать отдельные части:
var results = _localDatabase.Table<ArticleData>().Where(article =>
splitQuerry.All<string>(querryPart => article.ArticleName!.Contains(querryPart)));
В теории это звучало великолепно, но на практике у меня получилось Cannot compile: Lambda
исключение.
Мне нужен способ упаковать что-то вроде этого метода all или что-то вроде this в Linq-Expression.
У меня есть база данных SQLite. С помощью _localDatabase.Table<ArticleData>()
я получаю запрашиваемый объект.
Непонятно, что вы хотите запросить. Запрос как есть не может использовать какие-либо индексы для преобразований строк, и ему придется сканировать всю таблицу. Базы данных имеют Полнотекстовый поиск индексы и операции для поиска в нескольких полях слов или их вариантов. Какую базу данных и какой ORM вы используете? Возможно, существует способ написать запрос FTS с использованием ORM. В противном случае вам придется использовать, например, Dapper с SQL-запросом.
Спасибо @PanagiotisKanavos за отзыв: D Я работаю в приложении Blazor, которое загружает базу данных SQLite. Я использую SQLite-net для подключения к нему, а для запроса он использует Linq-выражения (насколько я понял). Я также видел полнотекстовый поиск, но SQLite ничего не предоставляет.
Вы можете использовать отдельное предложение Where
для каждого элемента в SplitQuerry:
var query = _localDatabase.Table<ArticleData>().AsQueryable();
foreach(var item in splitQuerry )
{
query = query.Where(article => article.ArticleName!.ToLower().Contains(item.ToLower()));
}
query = query.Skip(startIndex ?? 0).Take(requestedNumberOfItems ?? 5);
var result = query.ToList();
кажется, это работает. Спасибо большое :D Кстати, вы пропустили query
в query = *query*.Skip...
Пожалуйста, очистите вопрос и объясните, что вы на самом деле используете. LINQ не запрашивает базы данных. У EF нет
Table<T>
. ORM работают с O-объектами, а не с таблицами. Возможно, вы используете древний LINQ-to-SQL? В любом случае запуск другой задачи для выполнения запроса не ускорит ничего. Если в вашем ORM есть методToListAsync
, он не заблокирует текущий поток и не запустит другой заблокированный поток.