MVC中英土混合字符搜索报错:LINQ表达式类型转换失败
问题分析与修复方案
错误核心原因
你代码里的Where(infoItem.Contains(unaccentedText).ToString())写法完全错误:
Where方法要求传入Lambda表达式(用来判断集合中每个TestEntity是否符合过滤条件),但你传了一个字符串(infoItem.Contains(...)返回布尔值,ToString()后变成"True"/"False"),这直接导致类型转换错误。- 前面的
foreach循环毫无意义——它只是把最后一个遍历到的item的处理后值覆盖到infoItem和shortDescItem变量,完全没有利用循环内的其他数据,纯粹浪费性能。
修复后的完整代码
首先封装一个可复用的土耳其语去重音方法,避免重复代码:
private string RemoveTurkishAccents(string input) { if (string.IsNullOrEmpty(input)) return input; // 标准化字符并移除非间距标记,再替换土耳其语特定重音字符 var normalizedText = input.Normalize(NormalizationForm.FormD); var unaccentedBase = new string(normalizedText.Where(c => char.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark).ToArray()); return unaccentedBase .Replace('ş', 's').Replace('Ş', 'S') .Replace('ç', 'c').Replace('Ç', 'C') .Replace('ı', 'i').Replace('İ', 'I') .Replace('ü', 'u').Replace('Ü', 'U') .Replace('ö', 'o').Replace('Ö', 'O') .Replace('ğ', 'g').Replace('Ğ', 'G') .ToLower(); }
然后修正搜索方法的逻辑:
public PartialViewResult Search(string searchKey) { viewModel = new SearchModel(); viewModel.SearchKey = searchKey; // 处理搜索关键词的重音,转为无重音小写形式 var unaccentedSearchKey = RemoveTurkishAccents(searchKey); // 构建基础查询:过滤未删除、时间符合条件的数据 var baseQuery = _context.Test .Where(m => !m.IsDeleted && (m.StartDate < DateTime.Now && m.EndDate > DateTime.Now || m.StartDate == DateTime.MinValue || m.EndDate == DateTime.MinValue)) .OrderBy(m => m.Order); // 根据搜索关键词添加过滤条件 if (!string.IsNullOrEmpty(unaccentedSearchKey)) { viewModel.TestList = baseQuery .Where(m => RemoveTurkishAccents(m.Info).Contains(unaccentedSearchKey) || RemoveTurkishAccents(m.ShortDescription).Contains(unaccentedSearchKey)) .ToList(); } else { // 无搜索关键词时返回所有符合基础条件的数据 viewModel.TestList = baseQuery.ToList(); } return PartialView("ResultView", viewModel); }
额外优化建议
如果你的数据量较大,上述代码的客户端评估(在内存中处理每个实体的字段去重音)会影响性能。建议:
- 在数据库层面配置土耳其语排序规则(如
Turkish_CI_AS),让数据库直接支持无重音匹配。 - 创建数据库自定义函数处理去重逻辑,然后在EF中映射该函数,将过滤逻辑转移到数据库端执行。
内容的提问来源于stack exchange,提问作者user17847724
相关产品推荐
相关产品推荐

