Я взял код С#.
Код попадает в базу данных с некоторым SQL
, который использует параметры.
Все строковые параметры вводятся как DbType.AnsiString
вместо DbType.String
.
Почему вы использовали DbType.AnsiString
вместо DbType.String
?
Я взял код С#.
Код попадает в базу данных с некоторым SQL
, который использует параметры.
Все строковые параметры вводятся как DbType.AnsiString
вместо DbType.String
.
Почему вы использовали DbType.AnsiString
вместо DbType.String
?
AnsiString
Поток переменной длины символов, отличных от Unicode, от 1 до 8000 символов.
Строка
Тип, представляющий строки символов Unicode.
В базе данных:
nchar и nvarchar - это unicode
char и varchar не является unicode
Вы бы использовали ansistring вместо строки, чтобы избежать неявных преобразований в вашей базе данных SQL Server.
т.е. когда вы передаете строковую переменную в MSSQL, она выглядит как nvarchar (max). Учитывая тот факт, что хорошо спроектированная база данных в MSSQL может по умолчанию использовать varchars, а не nvarchars (если нет бизнес-требований для нелатинских наборов символов).
Строковая переменная в этом случае вызовет неявное преобразование в базе данных. Это может затем сделать движок неспособным использовать определенные индексы и выполнить полное сканирование таблицы (один из корней зла для производительности БД)
Почему вы используете DbType.AnsiString вместо DbType.String?
Краткий ответ: когда ваш SqlParameter
указывает на столбец базы данных varchar
(или char
), вы должны использовать DbType.AnsiString
. Когда вы указываете на столбец nvarchar
, используйте DbType.String
потому что это Unicode
.
Более длинный ответ: если они не сопоставлены точно (например, указание DbType.String
на DbType.String
varchar(nn)
, вы увидите предупреждения CONVERT_IMPLICIT
в ваших планах запросов, как описано Pinal Dave здесь: https://blog.sqlauthority.com/2018/06/11/SQL-сервер, как-к-FIX-convert_implicit-предупреждение/
В моем случае свойство SqlParameter.Size
также казалось важным: чтобы полностью исключить предупреждения CONVERT_IMPLICIT
мне нужно было правильно отобразить DbType
и Size
. Size
умолчанию, если он опущен, "выводится из фактического размера указанного значения параметра" (1), что обычно не соответствует определению реального размера столбца и также вызывает предупреждение.
Посмотрите, как решить проблему в С# с помощью Dapper:
SqlMapper.AddTypeMap(typeof(string), DbType.AnsiString);
SqlMapper.AddTypeMap(typeof(String), DbType.AnsiString);