有人对 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 生成的 SQL?
ServiceStack Webhook + ServiceStack.Webhooks.OrmLite 订阅商店插件问题
VeraCode 报告 ServiceStack OrmLite 对 SQL 命令中使用的特殊元素进行了不当中和(“SQL 注入”)(CWE ID 89)