在SQL Server的ntext列中使用LIKE运算符无法搜索俄文文本
解决EF Core中ntext列的西里尔文搜索问题
问题根源
你当前的代码先把所有数据加载到内存(ToListAsync)再做过滤,这会导致两个问题:
- 内存中的字符串比较依赖.NET的文化设置,和SQL Server的西里尔排序规则不匹配,所以找不到匹配项
- 全表加载数据效率极低,数据量大时性能会严重下降
解决方案
修改代码让过滤逻辑在数据库端执行,同时指定西里尔排序规则,和你手动执行的SQL逻辑对齐:
1. 调整仓储方法(核心修改)
public async Task<IEnumerable<Course>> GetAll(string searchString) { IQueryable<Course> query = _db.Courses.Include(c => c.Subcategory); if (!string.IsNullOrEmpty(searchString)) { // 用EF.Functions.Collate指定西里尔排序规则,同时让过滤逻辑在数据库执行 query = query.Where(c => EF.Functions.Collate(c.Subcategory.FullDescription, "Cyrillic_General_CI_AI") .Contains(searchString)); } return await query.ToListAsync(); }
2. 关键细节说明
- 延迟执行:通过
IQueryable构建查询,直到最后ToListAsync才触发数据库请求,过滤逻辑会被翻译成SQL在数据库端执行 - 排序规则指定:
EF.Functions.Collate会生成SQL中的COLLATE Cyrillic_General_CI_AI子句,和你手动测试的SQL逻辑一致 - Unicode参数:C#的
string本身是Unicode类型,EF Core会自动为Unicode列(ntext/nvarchar)生成带N前缀的参数,无需手动处理
3. 推荐优化:替换ntext为nvarchar(max)
ntext是SQL Server的过时类型,官方已不推荐使用,建议将列类型改为nvarchar(max):
- 在数据库中修改列类型
- 实体映射中更新配置(如果需要):
改用modelBuilder.Entity<Subcategory>() .Property(s => s.FullDescription) .HasColumnType("nvarchar(max)");nvarchar(max)后,EF Core的支持更完善,性能也更好。
内容的提问来源于stack exchange,提问作者Torekhan
相关产品推荐
相关产品推荐

