You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在SQL Server的ntext列中使用LIKE运算符无法搜索俄文文本

解决EF Core中ntext列的西里尔文搜索问题

问题根源

你当前的代码先把所有数据加载到内存(ToListAsync)再做过滤,这会导致两个问题:

  1. 内存中的字符串比较依赖.NET的文化设置,和SQL Server的西里尔排序规则不匹配,所以找不到匹配项
  2. 全表加载数据效率极低,数据量大时性能会严重下降

解决方案

修改代码让过滤逻辑在数据库端执行,同时指定西里尔排序规则,和你手动执行的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 04:52:44