有人对 ServiceStack Ormlite 中的 postgres jsonb 有问题吗?

Posted

技术标签:

【中文标题】有人对 ServiceStack Ormlite 中的 postgres jsonb 有问题吗?【英文标题】:Anyone have problems with postgres jsonb in ServiceStack Ormlite? 【发布时间】:2015-10-24 08:13:40 【问题描述】:

今天我正在使用 ServiceStack Ormlite 在 postgres 中使用 jsonb 数据类型。一个基本模型有一个复杂的类型属性,它本身包含一个接口对象的字典(下面的伪代码)。

通常,ServiceStack 通过向 json 添加一个“__type”标识符来处理这个问题。它正确地做到了这一点。但是,对于其中一个字典项,“__type”标识符列在属性下方的第二个位置,这导致从 postgres 检索该项时返回一个空对象。更有趣的是,据我所知,序列化程序首先列出了“__type”,但是一旦它存储在 postgres 中,它就会被重新排序。 jsonb 数据类型会重新排序 json 属性吗?

模型的伪代码(在真实代码中更广泛)

public class StrategyContainer

    public Dictionary<int, List<IStrategy>> SetOfStrategies  get; set; 


public interface IStrategy

    int Health  get; set; 
    string Name  get; set; 


public interface IAttack : IStrategy

    int Strength  get; set; 


public abstract class AbstractStrategy : IStrategy

    public int Health  get; set; 
    public string Name  get; set; 

public class Attack : AbstractStrategy, IAttack

    public int Strength  get; set; 

这是从 postgres jsonb 列检索时 json 的显示方式。


"SetOfStrategies": 
    "1": [
        "__type": "Test.Attack, Test",
        "Strength": 10,
        "Health": 5,
        "Name": "Testing"
    ,
    
        "Strength": 20,
        "__type": "Test.Attack, Test",
        "Health": 10,
        "Name": "Testing2"
    ]

注意:字典列表中还有许多其他项目。其中只有一个有错误的“__type”。所有其他正确加载。

现在我已经回到标准的文本列类型,一切正常。

【问题讨论】:

【参考方案1】:

jsonb 将 json 对象存储为字典,因此对象内的键顺序保留。坦率地说,我认为假设特定键顺序的应用程序有些损坏,但它们肯定存在。

如果您想保留键顺序(并保留重复键),您需要使用普通的 json 类型。这会验证 json,但不会对它做任何其他事情。缺点是它有更多有限的索引和数据库内运算符。

【讨论】:

【参考方案2】:

如果您不希望生成的 JSON 中包含 __type 信息,则不应使用 interfaces or late-bound objects in Data models。

特别是在跨进程边界(例如数据库、缓存、网络)持久化时,我会考虑避免使用 OOP 对象图,而是考虑使用干净的具体 POCO 模型(到处都有更可预测的行为)。

【讨论】:

谢谢神话。但是,在这种情况下,我非常想要类型信息,因为我专门对其进行了测试,并且我对 postgres 中的行为感到惊讶,因为它修改了 jsonb 中属性的顺序。通常我同意你只使用具体模型的想法。但是,我认为值得在这里记录,因为 SS 支持“__type”方法,而我看到的行为可能会导致非常意想不到的结果。

以上是关于有人对 ServiceStack Ormlite 中的 postgres jsonb 有问题吗?的主要内容,如果未能解决你的问题,请参考以下文章

ServiceStack OrmLite多对一关系

如何修改 ServiceStack.OrmLite 生成的 SQL?

ServiceStack.OrmLite 调用存储过程

ServiceStack Webhook + ServiceStack.Webhooks.OrmLite 订阅商店插件问题

VeraCode 报告 ServiceStack OrmLite 对 SQL 命令中使用的特殊元素进行了不当中和(“SQL 注入”)(CWE ID 89)

使用 ServiceStack.ORMLite 的存储库模式中的事务