EF LINQ查询中字符串大小写不敏感匹配返回null如何解决?
问题原因
EF.Functions.Like默认遵循数据库对应字段的排序规则,如果你的库/字段排序规则是大小写敏感(后缀为_CS),就无法匹配大小写不同的字符串,且你未加通配符的前提下,Like逻辑等价于直接等于比较。- 带
StringComparison.OrdinalIgnoreCase参数的字符串相等写法,EF Core不支持将该参数翻译为SQL语句,执行时要么忽略该参数按数据库默认排序规则做大小写敏感匹配,要么触发客户端评估(拉取全表数据到内存再比较),前者直接匹配失败,后者存在严重性能隐患。
正确实现方案
按推荐优先级排序如下:
方案1:查询时临时指定不区分大小写的排序规则(最推荐,不影响原有索引)
调用EF.Functions.Collate方法为查询字段指定大小写不敏感(后缀为_CI)的排序规则即可,不同数据库的排序规则名稍有差异,示例如下:
// SQL Server 示例,使用通用不区分大小写排序规则 var space = dbContext.Spaces.SingleOrDefault(a => EF.Functions.Collate(a.SpaceIdentity.DisplayName, "SQL_Latin1_General_CP1_CI_AS") == displayName); // MySQL 示例 // var space = dbContext.Spaces.SingleOrDefault(a => // EF.Functions.Collate(a.SpaceIdentity.DisplayName, "utf8mb4_general_ci") == displayName);
该方案不会破坏字段原有索引的使用,性能无损失。
方案2:字段配置层面固定不区分大小写排序规则
如果该字段业务上所有查询都需要忽略大小写,直接在模型映射时为字段指定CI排序规则,后续所有查询无需额外处理:
// 在DbContext的OnModelCreating方法中添加配置 modelBuilder.Entity<SpaceIdentity>() .Property(p => p.DisplayName) .UseCollation("SQL_Latin1_General_CP1_CI_AS"); // 按需替换为对应数据库的CI排序规则 // 后续查询直接写等于即可自动忽略大小写 var space = dbContext.Spaces.SingleOrDefault(a => a.SpaceIdentity.DisplayName == displayName);
方案3:统一大小写后比较(不推荐,性能较差)
如果不想修改排序规则,也可以将查询两端的字符串统一转为全大写/全小写后比较,缺点是会跳过字段索引,大数据量表查询性能差:
var space = dbContext.Spaces.SingleOrDefault(a => a.SpaceIdentity.DisplayName.ToLower() == displayName.ToLower());
内容的提问来源于stack exchange,提问作者Glory Raj
相关产品推荐
相关产品推荐

