有人对 ServiceStack Ormlite 中的 postgres jsonb 有疑问吗?
Anyone have problems with postgres jsonb in ServiceStack Ormlite?
今天我使用 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”。所有其他人都正确加载。
现在我已经改回标准文本列类型并且一切正常。
如果您不想在生成的 JSON 中包含 __type 信息,则不应使用 interfaces or late-bound objects in Data models。
特别是在跨进程边界(例如数据库、缓存、网络)持久化时,我会考虑避免使用 OOP 对象图并考虑使用干净的具体 POCO 模型(它们在任何地方都有更可预测的行为)。
jsonb
将 json 对象存储为字典,因此对象中的键顺序 未 保留。坦率地说,我认为采用特定键顺序的应用程序有些问题,但它们确实存在。
如果您想保留键顺序(并保留重复键),您需要使用普通 json
类型。这会验证 json,但不会对其执行任何其他操作。缺点是它的索引和数据库内运算符更加有限。
今天我使用 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”。所有其他人都正确加载。
现在我已经改回标准文本列类型并且一切正常。
如果您不想在生成的 JSON 中包含 __type 信息,则不应使用 interfaces or late-bound objects in Data models。
特别是在跨进程边界(例如数据库、缓存、网络)持久化时,我会考虑避免使用 OOP 对象图并考虑使用干净的具体 POCO 模型(它们在任何地方都有更可预测的行为)。
jsonb
将 json 对象存储为字典,因此对象中的键顺序 未 保留。坦率地说,我认为采用特定键顺序的应用程序有些问题,但它们确实存在。
如果您想保留键顺序(并保留重复键),您需要使用普通 json
类型。这会验证 json,但不会对其执行任何其他操作。缺点是它的索引和数据库内运算符更加有限。