我正在解决 .net core 应用程序上的 SonarQube 问题。我对 sonarQube 报告有一个问题,该报告要求在 LINQ 查询中的 ToString()、ToUpper()、ToLower() 等转换方法中添加文化信息。
查询示例:
var query = from emp in context.Employees
where emp.name.ToUpper() == name.ToUpper()
select emp;
如果我们添加
name.ToUpper(new CultureInfo("en-US", false))
那么查询将中断并出现以下错误。在应用此条件之前,我不想将此查询转换为 AsEnumerable。
无法翻译。附加信息:方法“string.ToUpper”的翻译失败。如果这个方法可以映射到你的自定义函数
有人可以帮我解决这个问题吗?
首先不要使用
emp.Name.ToUpper()
。这就是“真实的”、哥斯拉大小的虫子。 SonarQube 抱怨蚊子停在哥斯拉右前指甲(中间的指甲)上。建议的解决方案是去拍它。
EF Core 和数据库中的区分大小写和排序规则在排序规则和区分大小写中进行了解释,并明确警告不要使用 ToLower()
或
ToUpper()
:
通过 EF.Functions.Collate (或通过调用 string.ToLower)覆盖查询中的区分大小写可能会对应用程序的性能产生非常重大的影响。使用
ToUpper()
可防止数据库使用覆盖此列的任何索引。这意味着服务器现在必须扫描所有 100K 行,计算
UPPER()
的结果并将其与参数进行比较,而不是进行单个索引查找来在 100K 行表中查找一行。索引是根据实际列值创建的,使用由其排序规则指定的列区分大小写规则。在 SQL Server 中,默认使用区分大小写的排序规则。在其他数据库中,通常区分大小写。
您可以通过 EF.Functions.Collate
强制查询使用不同的排序规则,但这仍然会阻止服务器使用索引。在某些数据库中,您可以使用“不同”排序规则创建索引。在这两种情况下,服务器都会计算结果并将其存储在索引中。在其他数据库中,您可以基于原始内容使用不区分大小写的排序规则创建计算列并为其建立索引。您必须更改查询以使用新的不区分大小写的列才能利用索引