实体框架:在场景后面序列化/反序列化JSON列

Pav*_*sky 8 c# json entity-framework-4

我有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; }
}
Run Code Online (Sandbox Code Playgroud)

我更喜欢这样

public class Message
{
    [Key]
    public int Id { get; set; }
    public string Title { get; set; }
    [JSON]
    public MyClass JsonDefinition { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

其中JSON是一个自定义属性,它告诉EF将字段存储为MyClass实例的序列化字符串.同时它说EF:"一旦你拉动实体,用反序列化的MyClass实例替换JsonDefinition字符串"

现有的EF 4机制是否可以实现?如果是这样,那怎么样?

提前致谢.

编辑:MyClass可以是字典或任何其他复杂类型.

Lad*_*nka 8

不是直接的.您必须始终在类中包含字符串属性,因为EF要求它具有持久性.您还可以拥有非映射MyClass属性,但必须手动处理序列化和反序列化,并使这些属性保持同步.

天真的解决方案是INotifyPropertyChanged在MyClass中实现,并确保MyClass值或其任何属性的每次更改都会触发到字符串属性的JSON序列化.这种天真的解决方案适用于一些简单的问题,但在这种情况下,这是一个非常糟糕的主意,因为如果您在指定的属性上修改了很多属性,它会对性能产生很大影响MyClass.

另一种方法是使用EF的钩子进行物化并保存更改.您将需要处理ObjectContext.ObjectMaterialized的事件(你可以ObjectContextDbContext通过IObjectContextAdapter显式地实现DbContext).在此事件处理程序中,您将使用字符串属性的值并将其内容反序列化为MyClass属性.您还必须覆盖DbContext.SaveChanges您将查找Message应插入或更新的所有实例的位置,并使用其MyClass属性获取当前值并将其序列化为字符串属性.

您正在寻找的是一些复杂的映射方案或映射转换.EF不支持他们,但你可以投票给我关于Data UserVoice的建议.