Тип DateTimeType
NHibernate ожидает получения .Net DateTime
от устройства чтения данных, но SqlClient действительно выдает .Net DateTimeOffset
при чтении SQL Server DateTimeOffset
.Такой тип SQL должен быть сопоставлен с .Net DateTimeOffset
с использованием DateTimeOffset
типа NHibernate.
(Да, полученное вами сообщение об ошибке немного вводит в заблуждение, оно испускается перехватив ошибку Convert.ToDateTime(rs[index])
, где rs
- это DbDataReader
. В вашем случае, с SQL-сервером, rs[index]
возвращает DateTimeOffset
, который завершается неудачно преобразованием. В сообщении не должно упоминаться string
.)
Поскольку это работало с Oracle, я думаю, это означает, что ваш клиент Oracle выдает DateTime
при чтении типа timestamp with time zone
.Это весьма прискорбно, поскольку это означает потерю смещения, но также это означает, что тип DateTimeOffset
.Net не может поддерживаться Oracle.(Что ж, адаптер Entity Framework Oracle, кажется, поддерживает его, так что я думаю, что это все еще выполнимо, достигнув специфической реализации DbDataReader
для Oracle. Но это невозможно сделать, используя только то, что предоставляет DbDataReader
.)
Таким образом, проблема заключается в том, что несоответствие между клиентами Oracle и Sql-Server относительно типов с часовым поясом / смещением, первое из которых приводит к .Net DateTime
(кстати, какая цель служит смещению в вашем приложении, поскольку клиент Oracleне передает его?), второе дает .Net DateTimeOffset
.
Если, как и в вашем примере, вы храните все в UTC, возможно, стоит подумать об объявлении вашего столбца простым datetime2(6)
наСторона SQL-сервера.
Если вам нужно получить его с Kind
, правильно установленным как Utc
, то дополнительно сопоставьте его с типом NHibernate UtcDateTime
.
В противном случае, как написано по ewramner вам необходимо использовать пользовательский тип пользователя (класс, реализующий NHibernate.UserTypes.IUserType
).Его ссылка о типе пользователя для обработки .Net DateTimeOffset
с Oracle.Но в вашем случае вы захотите вместо этого написать класс пользовательского типа с методом NullSafeGet
, проверяющим, что дает считыватель данных, и конвертирующим его в DateTime
при необходимости.Затем в своем отображении используйте его, указав его квалифицированное имя сборки в качестве типа свойства.(См. Простую реализацию пользовательского типа здесь .)