У меня есть привычка всегда использовать общие абстракции в System.Data
, такие как IDbCommand
и IDbDataParameter
, для доступа к данным вместо конкретных реализаций System.Data.SqlClient.SqlDbCommand
и System.Data.SqlClient.SqlParameter
, когда это возможно, даже если мое приложение предназначеноSQL Server.Я делаю это так, чтобы в будущем было проще портировать приложение на другую СУБД или, при необходимости, ввести уровни абстракции базы данных между моим приложением и SQL Server.Я успешно использую этот шаблон уже более десяти лет.
Сегодня, однако, я столкнулся с очень странным поведением, когда использование IDbDataParameter
велось неожиданно.Используя код, подобный следующему:
System.Data.IDbCommand cmd;
TimeSpan someTimeSpanValue;
...
System.Data.IDbDataParameter dataParameter = cmd.CreateParameter();
dataParameter.DbType = DbType.Time;
dataParameter.Value = someTimeSpanValue;
cmd.Execute();
ADO.NET пожаловался, когда я выполнил свое заявление, что он не может преобразовать мой TimeSpan
в DateTime
.Базовый тип базы данных, который был установлен на основе этого параметра, имел тип TIME
.Смущенный, я проследил код и, конечно же, когда я установил dataParameter.DbType = DbType.Time
, а затем опросил dataParameter.DbType
, он вернул DbType.DateTime
вместо DbType.Time
, как я его установил.
У меня есть обходной путь к этому коду, который выглядит следующим образом:
dataParameter.DbType = v.DbType; //v.DbType is the desire DbType for the command being prepared
if (v.DbType == DbType.Time && dataParameter.DbType != DbType.Time && dataParameter is System.Data.SqlClient.SqlParameter sqlParam)
sqlParam.SqlDbType = SqlDbType.Time;
Кажется, когда я устанавливаю SqlDbType в SqlDbType.Time, а затем опрашиваю IDbDataParameter.DbType
, он возвращает DbType.Time
и все работает, хотя этот код теперь не так независим от базы данных, как хотелось бы.
Еще более странно, что если установить IDbDataParameter.DbType
в DbType.Time
(что является его текущим значением) после , установив SqlDbType в SqlDbType.Time, он все равно изменится на DbType.DateTime
.
Мой вопрос, после всего этого, заключается в том, является ли это дефектом в реализации System.Data.SqlClient
IDbDataParameter
или есть какая-то настройка, о которой я не знаю, которая вызывает такое поведение (возможно, по умолчанию предварительноСовместимость с -SQL 2008), которую можно настроить, чтобы избежать этого хакерского обходного пути?