将 DateTimeOffset 存储在 SQLite.Net

Store DateTimeOffset in SQLite.Net

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

我的几个数据模型(又名 tables)包含 DateTimeOffset 类型的属性。目的是存储这些而不丢失偏移信息。 (这是因为用户可以在指定日期/时间的同时输入时区信息,而这些信息必须存储在数据库中。)

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

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

=> 但对于这两种方法,我都需要向数据模型添加额外的属性,使用 [Ignore] 属性标记原始 DateTimeOffset 属性,并处理手动转换(在这两种方法中directions) - 因为我需要将它应用到很多不同的数据模型 类,它似乎很难维护。

=> 但在这种情况下,我需要定义自定义数据类型(以指定应如何存储 DateTimeTimeSpan 部分),并且不能使用默认值.NET DateTimeOffset 类型

=> 但这感觉有点老套,我需要确保只有 SQLiteNetExtensions 的扩展方法用于数据库插入/更新,而且我仍然需要额外的 string 属性 在所有数据模型上 类...

所以,我的问题是:是否有我缺少的更直接、更明显的解决方案?

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

方法 #1:

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

组成的移动应用程序
  • API数据模型类(用于序列化到/从JSON和上传到/从后端REST服务下载),
  • DB 数据模型类(表示 SQLite tables),以及
  • 用于 MVVM 样式表示层的各种 ViewModel 类

API 模型和数据库模型几乎相同(除了 JSON 序列化和 SQLite OR 映射所必需的属性),唯一的结构差异是表示日期/时间的属性是 string 在 API 类 和 DateTimeOffset 在数据库 类 中。从后台下载数据,上传数据之前,API和DB模型使用Automapper相互转换。

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

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

方法 #2:

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

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

此解决方案可作为 NuGet package, and has been open-sourced on GitHub 使用(GitHub 页面还包含详细的使用说明)。