[英]Store DateTimeOffset in SQLite.Net
In a WinRT (Windows 8.1 Store App) project, I'm using the SQLite.Net-PCL and SQLiteNetExtensions NuGet packages to store data in a local SQLite database file. 在WinRT(Windows 8.1 Store App)项目中,我使用SQLite.Net-PCL和SQLiteNetExtensions NuGet包将数据存储在本地SQLite数据库文件中。
Several of my data models (aka tables) contain properties of type DateTimeOffset
. 我的一些数据模型(也称为表)包含
DateTimeOffset
类型的属性。 The aim is to store these without losing the offset information . 目的是在不丢失偏移信息的情况下存储这些信息 。 (Reason for this is that the user can enter timezone information while specifying dates / times, and this information must be stored in the database.)
(原因是用户可以在指定日期/时间时输入时区信息,并且此信息必须存储在数据库中。)
I'm aware of the storeDateTimeAsTicks
parameter that can be set while creating the SQLiteConnection
, setting this to false
forces all DateTime
properties to be stored as text in ISO format - however, this has no consequences on DateTimeOffset
properties, as these are always automatically converted to UTC and stored as a number representing ticks. 我知道可以在创建
SQLiteConnection
时设置storeDateTimeAsTicks
参数,将其设置为false
强制所有DateTime
属性以ISO格式存储为文本 - 但是,这对DateTimeOffset
属性没有影响,因为它们总是自动转换到UTC并存储为代表刻度的数字。
I can think of the following 4 approaches: 我可以想到以下4种方法:
DateTimeOffset
to string
properties and store these, or DateTimeOffset
转换为string
属性并存储这些,或 DateTime
and offset (as TimeSpan
date type) parts of the DateTimeOffset
, and store these in two separate columns, DateTime
和偏移(如TimeSpan
日期型)的部件DateTimeOffset
,并且这些存储在两个单独的列, => but for both approaches, I'll need to add additional properties to the data model, flag the original DateTimeOffset
properties with the [Ignore]
attribute, and handle manual conversion (in both directions) - since I'd need to apply this to a lot of different data model classes, it seems too hard to maintain. =>但对于这两种方法,我需要向数据模型添加其他属性,使用
[Ignore]
属性标记原始DateTimeOffset
属性,并处理手动转换(在两个方向上) - 因为我需要应用此对很多不同的数据模型类来说,维护起来似乎太难了。
DateTime
and TimeSpan
(offset) parts of the DateTimeOffset
in two columns of a separate table, and maintain references to this separate table DateTime
和TimeSpan
(偏移)的部分DateTimeOffset
在一个单独的表中的两列,并维持到单独的表引用 => but in this case I'd need to define a custom data type (in order to specify how the DateTime
and TimeSpan
parts should be stored), and cannot use the default .NET DateTimeOffset
type =>但是在这种情况下我需要定义一个自定义数据类型(为了指定应该如何存储
DateTime
和TimeSpan
部分),并且不能使用默认的.NET DateTimeOffset
类型
TextBlob
attribute to somehow serialize the DateTimeOffset
to a single text column TextBlob
属性以某种方式将DateTimeOffset
序列化为单个文本列 => but this feels somewhat hacky, I'd need to make sure that only SQLiteNetExtensions' extension methods are used for DB insert / update, and I'd still need an additional string
property on all the data model classes... =>但这感觉有点hacky,我需要确保只有SQLiteNetExtensions的扩展方法用于数据库插入/更新,并且我仍然需要在所有数据模型类上增加一个
string
属性...
So, my question is: Is there a more straigtforward, obvious solution that I'm missing? 所以,我的问题是:我是否缺少一个更为直接,明显的解决方案?
Since nobody came up with potential solutions, but the question still received some attention, I decided to report how I solved the problem: 由于没有人提出可能的解决方案,但问题仍然引起了一些关注,我决定报告我是如何解决问题的:
Approach #1: 方法#1:
The very scenario that raised the original question included a mobile app consisting of 引发原始问题的场景包括一个由以下内容组成的移动应用程序
API models and DB models were nearly identical (except for attributes necessary for JSON serialization and SQLite OR mapping), the only structural difference being that properties representing dates / times were of type string
in the API classes and DateTimeOffset
in the DB classes. API模型和数据库模型几乎相同(除了JSON序列化和SQLite OR映射所需的属性),唯一的结构差异是表示日期/时间的属性在API类中是
string
类型,在DB类中是DateTimeOffset
。 After downloading data from, and before uploading data to the backend, API and DB models were converted into each other using Automapper. 从中下载数据之后,在将数据上传到后端之前,使用Automapper将API和DB模型相互转换。
I simply removed the string
to DateTimeOffset
conversion from the Automapper configuration, and modified the DB data model classes so that DateTimeOffset
values are represented as string
, which implies that they are stored as formatted text in SQLite (fortunately, no date / time calculations on the DB layer were required). 我只是从Automapper配置中删除了
string
到DateTimeOffset
转换,并修改了DB数据模型类,以便DateTimeOffset
值表示为string
,这意味着它们在SQLite中存储为格式化文本(幸运的是,没有日期/时间计算需要DB层)。 Since JSON objects received from the backend include timezone information, I could simply pass through those values to the DB models, thus ensuring that DB tables always contain dates / times as fully formatted datetime strings including timezone offset. 由于从后端接收的JSON对象包含时区信息,因此我可以简单地将这些值传递给数据库模型,从而确保数据库表始终包含日期/时间作为完全格式化的日期时间字符串,包括时区偏移量。
Conversion from string
to DateTimeOffset
now happens when creating ViewModel classes out of DB data models. 从DB数据模型创建ViewModel类时,现在会发生从
string
到DateTimeOffset
转换。 Obviously, this happens more often than before (when converting API models to DB models) resulting in a little overhead, but I can live with that since I don't need to worry about the SQLite data type issue any more. 显然,这种情况比以前更频繁(将API模型转换为数据库模型时)会产生一些开销,但我可以忍受这种情况,因为我不再需要担心SQLite数据类型问题了。
Approach #2: 方法#2:
Since approach #1 may not be applicable to all scenarios, I came up with an alternative solution that is based on the first one of the 4 potential solutions proposed in the original question, but with reduced manual effort: 由于方法#1可能不适用于所有方案,我提出了一个替代解决方案,该解决方案基于原始问题中提出的4个潜在解决方案中的第一个,但减少了手动工作:
I created a custom attribute [DateTimeOffsetSerialize]
that can be assigned to DateTimeOffset
properties in SQLite data model classes, and a postbuild task that decompiles the assembly after build has finished and scans all classes within the assembly to find those flagged properties. 我创建了一个可以分配给SQLite数据模型类中的
DateTimeOffset
属性的自定义属性[DateTimeOffsetSerialize]
,以及一个在构建完成后反编译程序集的postbuild任务,并扫描程序集中的所有类以查找那些标记的属性。 For each of these flagged properties, a duplicate property of type string
is created automatically that contains the original property's serialized value, and this newly created string
property will be used as SQLite table column (the original DateTimeOffset
property is automatically flagged with the [Ignore]
attribute). 对于这些标记属性中的每一个,将自动创建包含原始属性的序列化值的
string
类型的重复属性,并且此新创建的string
属性将用作SQLite表列(原始DateTimeOffset
属性将使用[Ignore]
自动标记[Ignore]
属性)。
This solution is available as NuGet package , and has been open-sourced on GitHub (the GitHub page also contains details usage instructions). 该解决方案以NuGet包的形式提供 ,并且已在GitHub上开源 (GitHub页面还包含详细的使用说明)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.