Dapper и varchars

Я нашел следующий комментарий на домашней странице проекта Dapper.NET.

Dapper поддерживает параметры varchar, если вы выполняете предложение where в столбце varchar, используя параметр, обязательно передайте его следующим образом:

    Query<Thing>("select * from Thing where Name = @Name", new {Name = 
    new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = true });

На сервере Sql крайне важно использовать unicode при запросе unicode и ansi при запросе un unicode

Я оцениваю Dapper для использования с устаревшей базой данных (SQL Server 2008), с множеством хранимых процедур с параметрами varchar, и я немного смущен этим ограничением.

С помощью кода ADO.NET, созданного вручную, для вышеуказанного запроса я бы использовал следующее:

new SqlParameter("@Name", "abcde")

без указания того, является ли он unicode или нет, или длина.

  • Почему мне нужен этот подробный синтаксис DbString с Dapper, указав длину столбца, IsFixedLength и IsAnsi?

  • Почему IsFixedLength = true для столбца varchar (я ожидаю, что это будет верно для столбца char или nchar)?

  • Нужно ли использовать DbString для параметров хранимой процедуры?

Я ожидал, что Dapper сделает мой код DAL более кратким, но это, кажется, делает его более подробным для параметров varchar.

UPDATE

Я исследовал немного дальше, чтобы понять, почему Dapper будет иметь это ограничение varchar, которое, как мне кажется, не имеет в моем коде с ручным управлением, где я обычно создаю входной параметр следующим образом:

var parameter = factory.CreateParameter(); // Factory is a DbProviderFactory
parameter.Name = ...;
parameter.Value = ...;

и обычно оставляют провайдера для вывода DbType с использованием своих собственных правил, если я специально не хочу его принуждать.

Рассматривая класс Dapper DynamicParameters, он имеет метод AddParameters, который создает параметры следующим образом:

var dbType = param.DbType; // Get dbType and value
var val = param.Value;     // from 

...
// Coerce dbType to a non-null value if val is not null !!!!!
if (dbType == null && val != null) dbType = SqlMapper.LookupDbType(val.GetType(),name);
...
var p = command.CreateParameter();
...
if (dbType != null)                     
{                         
    p.DbType = dbType.Value;                     
}

т.е. он явно принуждает IDataParameter.DbType к значению, которое он ищет своим собственным алгоритмом, вместо того, чтобы оставлять провайдера для использования своих собственных правил.

Есть ли веская причина для этого? Это кажется неправильным для меня, особенно в свете комментария о поддержке Dapper для параметров varchar.

Ответ 1

Вам нужен этот синтаксис при работе с ODBC.

Вам нужно будет определить поле CHAR (30) как DbString в С# для Dapper, а также установить значения длины (30) и ansi (true), чтобы предотвратить использование Dapper в строке типа text/blob, В противном случае вы, скорее всего, получите сообщение об ошибке: "Незаконная попытка конвертировать текст/тип байта blob".

Я получал эту ошибку, используя ODBC для подключения к Informix, пока не определил свой параметр как DbString() и не установил значения длины и ansi.

Подробнее здесь.

Ответ 2

var param = new { Varchar1 = "", Varchar2 = "" };
db.Query("SP", param, commandType:CommandType.StoredProcedure);