С#: DbType.String по сравнению с DbType.AnsiString

Я взял код С#.

Код попадает в базу данных с некоторым SQL, который использует параметры.

Все строковые параметры вводятся как DbType.AnsiString вместо DbType.String.

Почему вы использовали DbType.AnsiString вместо DbType.String?

Ответ 1

AnsiString
Поток переменной длины символов, отличных от Unicode, от 1 до 8000 символов.

Строка
Тип, представляющий строки символов Unicode.

В базе данных:

nchar и nvarchar - это unicode

char и varchar не является unicode

Ответ 2

Вы бы использовали ansistring вместо строки, чтобы избежать неявных преобразований в вашей базе данных SQL Server.

т.е. когда вы передаете строковую переменную в MSSQL, она выглядит как nvarchar (max). Учитывая тот факт, что хорошо спроектированная база данных в MSSQL может по умолчанию использовать varchars, а не nvarchars (если нет бизнес-требований для нелатинских наборов символов).

Строковая переменная в этом случае вызовет неявное преобразование в базе данных. Это может затем сделать движок неспособным использовать определенные индексы и выполнить полное сканирование таблицы (один из корней зла для производительности БД)

Ответ 3

Почему вы используете 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), что обычно не соответствует определению реального размера столбца и также вызывает предупреждение.

  1. https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlparameter.size?view=netframework-4.7.2

Ответ 4

Посмотрите, как решить проблему в С# с помощью Dapper:

SqlMapper.AddTypeMap(typeof(string), DbType.AnsiString);
SqlMapper.AddTypeMap(typeof(String), DbType.AnsiString);