如何通过LINQ实现Card实体Title属性的多关键词模糊搜索?
解决方案
你的需求是搜索词拆分为多个单词后,只要卡片标题包含其中任意一个单词就返回该卡片,原代码的问题在于Contains方法的参数使用错误,以下是修正后的完整代码及逻辑说明:
修正后的代码
public IActionResult All(string searchTerm) { var cardsQuery = this.data.Cards.AsQueryable(); if (!string.IsNullOrWhiteSpace(searchTerm)) { // 拆分搜索词,去除空项并统一转小写 var searchTerms = searchTerm.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries) .Select(term => term.ToLower()) .ToList(); // 筛选逻辑:卡片标题转小写后,包含任意一个搜索词即保留 cardsQuery = cardsQuery .Where(c => searchTerms.Any(term => c.Title.ToLower().Contains(term))); } var cards = cardsQuery .OrderByDescending(c => c.Id) .Select(c => new CardListingViewModel { Title = c.Title, ImageUrl = c.ImageUrl, Category = c.Category.Name, Condition = c.Condition.Name }) .ToList(); return View(new AllCardsQueryModel { Cards = cards }); }
逻辑说明
- 搜索词处理:将输入的搜索词按空格拆分,移除空字符串(比如连续空格的情况),并统一转成小写,避免大小写敏感的匹配问题。
- 筛选逻辑:使用
Any方法判断:对于当前卡片的标题(转小写后),是否包含搜索词列表中的任意一个单词。- 当搜索
Magician Dragon时,拆分出magician和dragon两个词,Dark Magician包含magician,Blue Eyed Dragon包含dragon,因此两张卡片都会被返回。 - 当搜索
Blue dog with a house时,拆分出blue、dog、with、a、house,只有Blue Eyed Dragon的标题包含blue,因此仅返回该卡片。
- 当搜索
注意事项
如果你的项目使用EF Core,这个查询会被正确翻译为SQL语句执行(避免客户端评估的性能问题),但要确保数据库的LIKE查询支持大小写不敏感(或者通过配置EF Core的字符串比较规则来统一)。
内容的提问来源于stack exchange,提问作者Alexander Nedelchev
相关产品推荐
相关产品推荐

