【问题标题】:ServiceStack Ormlite - Postgres serializing Date property with MaxDate to JsonBServiceStack Ormlite - Postgres 使用 MaxDate 将 Date 属性序列化为 JsonB
【发布时间】:2016-03-16 11:59:03
【问题描述】:

我有一个复杂的对象,我使用 Ormlite 将它保存到 postgres 中的 JsonB 字段中。 其中一个属性是 DateTime,设置为 DateTime.Max。

从 Postgres 中检索对象将 DateTime 属性值设置为 DateTime.Min 值

01/01/0001 00:00:00

不确定这是 Ormlite 还是 json 序列化程序的错误。

要复制的代码 sn-p

class Program
{
    static void Main(string[] args)
    {
        var item = new LicenseCheckTemp();
        item.Body = new CheckHistory();
        item.Body.List.Add(new ItemHistory() {AddedOn = DateTime.MaxValue, Note = "Test"});

        var factory = GetFactory(ConfigurationManager.AppSettings["PostgresConnectionString"]);
        using (var db = factory.OpenDbConnection())
        {
            db.CreateTableIfNotExists<LicenseCheckTemp>();
            db.Save(item);
        }

        using (var db = factory.OpenDbConnection())
        {
          var items =  db.Select<LicenseCheckTemp>();

            foreach (var licenseCheck in items.OrderBy(x=>x.Id))
            {
                if (licenseCheck.Body != null && licenseCheck.Body.List.Any())
                {
                    foreach (var itemHistory in licenseCheck.Body.List)
                    {
                        Console.WriteLine($"{itemHistory.AddedOn} :  Note {itemHistory.Note}");
                    }

                }

            }
        }

        Console.ReadKey();


    }


    public static IDbConnectionFactory GetFactory(string connection)
    {
        var factory = new OrmLiteConnectionFactory(connection,
           PostgreSqlDialect.Provider);

        factory.DialectProvider.NamingStrategy = new OrmLiteNamingStrategyBase();

        return factory;
    }
}

public class LicenseCheckTemp
{
    [AutoIncrement]
    public int Id { get; set; }

    [CustomField("json")]
    public CheckHistory Body { get; set; }
}

public class CheckHistory
{
    public List<ItemHistory> List { get; set; } = new List<ItemHistory>();
}

public class ItemHistory
{
    public string Note { get; set; }

    public DateTime AddedOn { get; set; }

}

【问题讨论】:

  • 请发布显示问题的确切源代码。
  • 嗨,mythz,添加了代码 sn-p

标签: postgresql servicestack ormlite-servicestack


【解决方案1】:

虽然 OrmLite 没有明确支持 PostgreSQL JSON DataTypes,但 OrmLite 现有的 ComplexType 属性的 JSON 序列化应该可以让它自然地工作,如下所示:

我添加了this test in this commit 的示例:

OrmLiteConfig.DialectProvider.NamingStrategy = new OrmLiteNamingStrategyBase();

var item = new LicenseCheckTemp();
item.Body = new CheckHistory();
item.Body.List.Add(new ItemHistory { AddedOn = DateTime.MaxValue, Note = "Test" });

using (var db = OpenDbConnection())
{
    db.DropAndCreateTable<LicenseCheckTemp>();
    db.GetLastSql().Print();
    db.Save(item);
}

using (var db = OpenDbConnection())
{
    var items = db.Select<LicenseCheckTemp>();
    items.PrintDump();

    foreach (var licenseCheck in items.OrderBy(x => x.Id))
    {
        if (licenseCheck.Body != null && licenseCheck.Body.List.Any())
        {
            foreach (var itemHistory in licenseCheck.Body.List)
            {
                $"{itemHistory.AddedOn} :  Note {itemHistory.Note}".Print();
            }
        }
    }
}

按预期工作,即打印出来:

CREATE TABLE "LicenseCheckTemp" 
(
  "Id" INTEGER PRIMARY KEY AUTOINCREMENT, 
  "Body" json NULL 
); 

[
    {
        Id: 1,
        Body: 
        {
            List: 
            [
                {
                    Note: Test,
                    AddedOn: 9999-12-31T23:59:59.9999999-05:00
                }
            ]
        }
    }
]
12/31/9999 11:59:59 PM :  Note Test

显示 CreateTable 为 Body 属性创建“json”类型,其中行被序列化并返回完全填充。

无法重现为什么它不适合您,您使用的是 OrmLite 的最新 v4.0.54 版本吗?它适用于较小的日期时间吗? (也许您的 TimeZone 中的 Max DateTime 超过了您的 PgSql 配置实例支持的时间)。

【讨论】:

  • 我正在使用 PostgreSQL 9.5 的 4.0.54 版本。查看存储在 PostgreSQL 中的打印日期看起来不一样 {"List":[{"Note":"Test","AddedOn":"\/Date(253402300800000-0000)\/"}]} .我假设存储日期的方式是标准的,我可以设置任何其他设置来获取像您的输出一样的日期吗?
  • @laitang 在 JSON 中存储日期没有标准方法,ServiceStack.Text 默认为 WCF JSON 日期。您可以使用 JsConfig.DateHandler = ... 和任何 DateHandler Enum Values 更改默认 DateFormat
  • 谢谢!更改为 JsConfig.DateHandler = DateHandler.ISO8601 解决了问题。
猜你喜欢
  • 2015-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多