[英]Persisting Nodatime Instant in SQL Server with ServiceStack / OrmLite
我正在使用NodaTime Instant
在我的DTO中使用ServiceStack存儲日期/時間。 我已將DTO中的SQL類型指定為datetimeoffset
,ServiceStack正確地創建了具有該類型的表。 但是,保存后,我得到一個InvalidCastException
。
簡單的例子:
public class ItemWithInstant
{
public int Id { get; set; }
public string Name { get; set; }
[CustomField("DateTimeOffset")
public Instant DateCreated { get; set; }
}
在服務中:
public object Post(CreateItemWithInstant request)
{
var dto = request.ConvertTo<ItemWithInstant>();
Db.Save(dto); // ERROR here
return dto;
}
特定錯誤是InvalidCastException ,其詳細信息無法將參數值從Instant轉換為String。
當數據庫類型為DateTimeOffset
時,不知道為什么它會轉換為字符串。 我是否需要告訴ServiceStack如何將值轉換為適用於SQL類型的值?
感謝@mythz的回答,我創建了一個自定義轉換器。 我最終還是以DATETIME2
獲取SQL數據類型(不要認為這會產生很大的不同):
public class SqlServerInstantToDatetimeConverter : OrmLiteConverter
{
public override string ColumnDefinition { get { return "DATETIME2"; } }
public override DbType DbType { get { return DbType.DateTimeOffset; } }
public override object ToDbValue(Type fieldType, object value)
{
var instantValue = (Instant) value;
return instantValue.ToDateTimeUtc();
}
public override object FromDbValue(Type fieldType, object value)
{
var datetimeValue = DateTime.SpecifyKind((DateTime)value, DateTimeKind.Utc);
return Instant.FromDateTimeUtc(datetimeValue);
}
}
然后我在AppHost.cs
文件中注冊了它:
Register<IDbConnectionFactory>(new OrmLiteConnectionFactory(Settings.Default.LocalSqlConnectionString, SqlServerDialect.Provider));
SqlServerDialect.Provider.RegisterConverter<Instant>(new SqlServerInstantConverter());
不要忘記FromDbType
覆蓋。 我最初忘記了它並且沒有輸出該字段。
另一個警告 - 由於ServiceStack想要本地化所有日期,我不得不使用此答案中的信息強制所有日期到DateTimeKind.Local
[CustomField]
告訴OrmLite在創建表時使用哪個列定義,即它沒有提供OrmLite如何處理未知類型的任何指示。
您可以通過注冊最新v4.0.44版本中現在提供的自定義類型轉換器來支持新字段類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.