EF Core按名称查询时,带索引的字符串列是否需要区分大小写?
问题解答
1. 大小写不一致是否会影响查询结果
取决于你数据库对应UserName列配置的排序规则(Collation):
- 若排序规则为不区分大小写(名称带
CI后缀,例如SQL Server的SQL_Latin1_General_CP1_CI_AS、MySQL的utf8mb4_general_ci),则输入MIKE/mike/MIke都可以匹配到库中存储的Mike,不会影响查询结果。 - 若排序规则为区分大小写(名称带
CS后缀),则大小写不一致时无法匹配,会直接影响查询结果。
2. 不区分大小写的查询是否会影响性能
分两种场景:
- 如果
UserName列本身就配置了不区分大小写的排序规则,且已经创建了索引,那么原生的等值查询(对应你给出的第一段代码)可以正常命中索引,不会有性能损失。
var poses = await _dbContext.Users .FirstOrDefaultAsync(p => p.UserName == userName);
- 如果
UserName列是区分大小写的排序规则,你为了实现不区分大小写查询,在查询时对字段做转换操作(比如写p => p.UserName.ToUpper() == userName.ToUpper()),EF生成的SQL会对UserName列调用函数,导致无法命中索引,触发全表扫描,数据量较大时性能会大幅下降。
3. 是否需要额外创建标准化大写存储列
这是非常成熟且通用的解决方案,优先推荐使用:
- 优势:完全不需要考虑不同数据库的排序规则差异,只要给
NormalizedUserName列创建索引,查询时先把输入参数转大写再匹配,就能稳定命中索引,性能和区分大小写的查询完全一致。ASP.NET Core Identity框架默认就采用了这套设计,兼容性和稳定性都经过验证。
var poses = await _dbContext.Users .FirstOrDefaultAsync(p => p.NormalizedUserName == userName.ToUpper());
- 如果你不需要兼容多数据库,也可以直接把
UserName列的排序规则修改为不区分大小写,不需要额外加列,也能达到同样的效果。
内容的提问来源于stack exchange,提问作者chuckd
相关产品推荐
相关产品推荐

