Я нашел следующий комментарий на домашней странице проекта 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.