我已经接管了一些 C# 代码。
该代码正在使用一些SQL
使用参数的数据库。
所有字符串参数都输入为DbType.AnsiString
而不是DbType.String
.
你为什么要使用DbType.AnsiString
而不是DbType.String
?
AnsiString
可变长度的非 Unicode 字符流,范围在 1 到 8,000 个字符之间。
String
表示 Unicode 字符串的类型。
在数据库中:
nchar 和 nvarchar 是 unicode
char 和 varchar 是非 unicode
您将使用 ansistring 而不是 string 以避免 SQL Server 数据库中的隐式转换。
即,当您将字符串变量传递给 MSSQL 时,它显示为 nvarchar(max)。鉴于 MSSQL 中设计良好的数据库默认情况下可能使用 varchars 而不是 nvarchars(除非有非拉丁字符集的业务需求)。
在这种情况下,字符串变量将导致数据库中的隐式转换。这可能会导致引擎无法使用某些索引并执行全表扫描(数据库性能万恶之源之一)
为什么要使用 DbType.AnsiString 而不是 DbType.String?
简短回答:当您SqlParameter
指向varchar
(或char
)数据库列时,您将使用DbType.AnsiString
. 当您指向一nvarchar
列时,请使用DbType.String
因为它的Unicode
.
更长的答案:如果这些映射不准确(例如指向DbType.String
一varchar(nn)
列,您将CONVERT_IMPLICIT
在查询计划中看到警告,如 Pinal Dave 所述:https ://blog.sqlauthority.com/2018/06/11/sql-server -how-to-fix-convert_implicit-warnings/
在我的情况下,该SqlParameter.Size
属性似乎也很重要:为了完全消除CONVERT_IMPLICIT
我必须正确映射的DbType
警告 Size
。如果省略,则默认Size
值“从指定参数值的实际大小推断”(1),这通常与实际列大小定义不匹配,并且也会引发警告。
了解如何使用 Dapper 在 C# 中解决问题:
SqlMapper.AddTypeMap(typeof(string), DbType.AnsiString);
SqlMapper.AddTypeMap(typeof(String), DbType.AnsiString);