实体框架:在场景后面序列化/反序列化JSON列
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实体框架:在场景后面序列化/反序列化JSON列相关的知识,希望对你有一定的参考价值。
我有Code First类/表,其中一个字段有string / nvarchar类型。此字符串是MyClass实例的JSON表示形式。我想在仅使用MyClass实例的代码中操作,但是将其作为字符串(JSON)存储在数据库中。假设我的表看起来像这样:
public class Message
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
public string JsonDefinition { get; set; }
}
我更喜欢这样
public class Message
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
[JSON]
public MyClass JsonDefinition { get; set; }
}
其中JSON是一个自定义属性,它告诉EF将字段存储为MyClass实例的序列化字符串。同时它说EF:“一旦你拉动实体,用反序列化的MyClass实例替换JsonDefinition字符串”
现有的EF 4机制是否可以实现?如果是这样,那怎么样?
提前致谢。
编辑:MyClass可以是字典或任何其他复杂类型。
不是直接的。您必须始终在类中包含字符串属性,因为EF要求它具有持久性。您还可以使用非映射的MyClass
属性,但必须手动处理序列化和反序列化并使这些属性同步。
天真的解决方案是在MyClass中实现INotifyPropertyChanged
,并确保MyClass
值或其任何属性中的每个更改都将触发JSON序列化到字符串属性。这种天真的解决方案适用于一些简单的问题,但在这种情况下,这是一个非常糟糕的主意,因为如果您在指定的MyClass
属性上修改了很多属性,它会产生很大的性能影响。
另一种方法是使用EF的钩子进行物化并保存更改。你需要处理ObjectContext.ObjectMaterialized
事件(你可以通过ObjectContext
明确实施的DbContext
从IObjectContextAdapter
获得DbContext
)。在此事件处理程序中,您将使用字符串属性的值并将其内容反序列化为MyClass
属性。您还必须覆盖DbContext.SaveChanges
,您将在其中查找应插入或更新的所有Message
实例,并使用其MyClass
属性获取当前值并将其序列化为字符串属性。
您正在寻找的是一些复杂的映射方案或映射转换。 EF不支持他们,但你可以投票给我对Data UserVoice的建议。
我会尝试如下:
public class Message
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
[Column(TypeName = "jsonb")]
[JsonIgnore]
public string JMyClass { get; set; }
[NotMapped]
public MyClass JsonDefinition
{
get => JsonConvert.DeserializeObject<MyClass>(JMyClass );
set => JMyClass = JsonConvert.SerializeObject(value);
}
}
以上是关于实体框架:在场景后面序列化/反序列化JSON列的主要内容,如果未能解决你的问题,请参考以下文章