В последнее время мы столкнулись следующий вопрос:Безопасно ли всегда вводить DBNull SqlParameter как int?
В двух словах: myCommand.Parameters.AddWithValue("@SomeParameter", DBNull.Value);
, по-видимому «типа» Параметр, DBNull как NVARCHAR, который может быть неявно преобразован в почти все другие типы, но, к сожалению, не varbinary
, что приводит к следующей ошибке:
Implicit conversion from data type nvarchar to varbinary(max) is not allowed. Use the CONVERT function to run this query.
К сожалению, решения, предложенные в связанном вопросе, не применяются, поскольку мы используем AddWithValue
внутри библиотеки доступа к данным, которая предназначена для вывода типа данных из типа параметра и не поддерживает добавление «реального» типа SQL Server.
I "фиксированный" этот вопрос явным образом введя параметры DBNull в int
с вместо:
void MyImprovedAddWithValue(SqlCommand cmd, string key, object value)
{
if (value == DBNull.Value)
{
cmd.Parameters.Add(key, SqlDbType.Int).Value = DBNull.Value;
}
else
{
cmd.Parameters.AddWithValue(key, value);
}
}
Это кажется работать. По-видимому, NULL, введенный как int , может быть неявным образом преобразован в любой другой тип, поддерживаемый SQL Server.
Игнорируя тот факт, что AddWithValue has some well-known shortcomings (что мы прекрасно знаем), есть ли какие-либо проблемы, ожидающие использования этого подхода? У дизайнеров SqlParameterCollection.AddWithValue
есть веская причина не делать это «по умолчанию», которые я пропускаю?
AddWithValue работает с DBNULL, у вас будут проблемы, когда значение == null –
Я предлагаю полностью исключить AddWithValue и явно указать правильный тип параметра. Это не только предотвратит сюрпризы, но и улучшит производительность, в некоторых случаях значительно. –
Все хорошо и хорошо, когда вы создаете параметры в коде верхнего уровня, но не имеет большого смысла для фреймворка или API, который строит SqlParameters глубоко внутри слоев извлечения. –