C# 在SQLite.Net中存储DateTimeOffset

C# 在SQLite.Net中存储DateTimeOffset,c#,.net,sqlite,datetimeoffset,C#,.net,Sqlite,Datetimeoffset,在WinRT(Windows 8.1应用商店)项目中,我使用SQLite.Net-PCL和SQLiteNetExtensions NuGet包将数据存储在本地SQLite数据库文件中 我的几个数据模型(也称为表)包含类型为DateTimeOffset的属性。目的是在不丢失偏移信息的情况下存储这些信息。(原因是用户可以在指定日期/时间时输入时区信息,并且该信息必须存储在数据库中。) 我知道在创建SQLiteConnection时可以设置storeDateTimeAsTicks参数,将其设置为fal

在WinRT(Windows 8.1应用商店)项目中,我使用SQLite.Net-PCL和SQLiteNetExtensions NuGet包将数据存储在本地SQLite数据库文件中

我的几个数据模型(也称为表)包含类型为
DateTimeOffset
的属性。目的是在不丢失偏移信息的情况下存储这些信息。(原因是用户可以在指定日期/时间时输入时区信息,并且该信息必须存储在数据库中。)

我知道在创建
SQLiteConnection
时可以设置
storeDateTimeAsTicks
参数,将其设置为
false
将强制所有
DateTime
属性以ISO格式存储为文本-但是,这对
DateTimeOffset
属性没有影响,因为它们总是自动转换为UTC,并存储为表示刻度的数字

我可以想到以下4种方法:

  • 手动将
    DateTimeOffset
    转换为
    string
    属性并存储这些属性,或
  • 提取
    DateTimeOffset
    DateTime
    和offset(作为
    TimeSpan
    日期类型)部分,并将它们存储在两个单独的列中
=>但是对于这两种方法,我都需要向数据模型添加额外的属性,用
[Ignore]
属性标记原始的
DateTimeOffset
属性,并处理手动转换(在两个方向上)-因为我需要将其应用于许多不同的数据模型类,所以维护起来似乎太困难了

  • DateTimeOffset
    DateTime
    TimeSpan
    (偏移量)部分存储在单独表格的两列中,并维护对此单独表格的引用
=>但是在这种情况下,我需要定义一个自定义数据类型(以便指定如何存储
DateTime
TimeSpan
部分),并且不能使用默认的.NET
DateTimeOffset
类型

  • 使用SQLiteNetExtensions的
    TextBlob
    属性以某种方式将
    DateTimeOffset
    序列化为单个文本列
=>但这感觉有点骇人,我需要确保只有SQLiteNetExtensions的扩展方法用于DB insert/update,并且我仍然需要在所有数据模型类上增加一个
string
属性


因此,我的问题是:有没有一个我缺少的更具前瞻性、更明显的解决方案?

由于没有人提出可能的解决方案,但这个问题仍然受到一些关注,我决定报告我是如何解决这个问题的:

方法#1:

提出最初问题的场景包括一个由

  • API数据模型类(用于序列化到JSON或从JSON进行序列化,以及上传到后端REST服务或从后端REST服务下载)
  • DB数据模型类(表示SQLite表),以及
  • 用于MVVM样式表示层的各种ViewModel类
API模型和DB模型几乎相同(除了JSON序列化和SQLite或映射所需的属性),唯一的结构差异是,表示日期/时间的属性在API类中为
string
类型,在DB类中为
DateTimeOffset
。从下载数据后,在将数据上载到后端之前,使用Automapper将API和DB模型相互转换

我只是从Automapper配置中删除了
string
DateTimeOffset
的转换,并修改了DB数据模型类,使
DateTimeOffset
值表示为
string
,这意味着它们在SQLite中存储为格式化文本(幸运的是,不需要在DB层上计算日期/时间)。由于从后端接收的JSON对象包含时区信息,我可以简单地将这些值传递给DB模型,从而确保DB表始终包含日期/时间作为完全格式化的datetime字符串,包括时区偏移量

从DB数据模型创建ViewModel类时,现在会发生从
string
DateTimeOffset
的转换。显然,这种情况比以前更频繁(将API模型转换为DB模型时)这会导致一些开销,但我可以接受,因为我不再需要担心SQLite数据类型问题

方法#2:

由于方法#1可能不适用于所有场景,因此我提出了一个替代解决方案,该方案基于原始问题中提出的4个潜在解决方案中的第一个,但减少了手动操作:

我创建了一个自定义属性
[DateTimeOffsetSerialize]
可以分配给SQLite数据模型类中的
DateTimeOffset
属性,以及一个生成后任务,该任务在生成完成后反编译程序集,并扫描程序集中的所有类以查找标记的属性。对于这些标记的属性中的每一个,都会创建一个类型为
string
的重复属性自动包含原始属性的序列化值,此新创建的
字符串
属性将用作SQLite表列(原始
DateTimeOffset
属性自动标记为
[忽略]
属性)


此解决方案已提供(GitHub页面还包含详细的使用说明).

我还没有成功测试过它,但是您是否尝试过使用SQLite.Net.DateTimeOffset nuGet软件包?使用说明文件在这里:谢谢@nullPainter-我自己编写并发布了nuGet库,因为没有人能回答我的问题。我可能应该在我有更多时间后尽快发布问题的答案…不