使用 Entity Framework 6.1 代码优先保存和检索序列化实体 属性
Persisting and retrieving serialized entity property with Entity Framework 6.1 code first
示例:假设我有这三个 类。 Foo
是一个带有 DbSet 的正确 Entity Framework 实体,而我希望我的 EF DbContext 不知道 Bar
和 Baz
因为我已经用 Foo 的 Bar 属性 标记了我组成的 SerializedColumn
属性。通过应用该属性,我希望 EF 将 Bar 的实例及其 Bazes 序列化为单个字符串字段,并在 EF 实现 Foo 时透明地将 Bar 反序列化为 Bar 对象。
public class Foo
{
public Guid Id { get; set; }
[SerializedColumn]
public Bar Bar { get; set; }
// ..
}
public class Bar
{
public string Name { get; set; }
public Baz[] Baz { get; set; }
// ..
}
public class Baz
{
public string Name { get; set; }
// ..
}
所以 Foo 的 table 列看起来像:
[Id] [uniqueidentifier] NOT NULL
[Bar] [nvarchar](max) NULL
当我查询 Foo
时,我返回一个 Bar
属性 已经反序列化的查询。当我插入或更新 Foo
时,Bar
属性 会被 EF 序列化,而我无需考虑它。我唯一需要做的就是将 [SerializeColumn]
属性添加到属性中。
目标:
- 我不一定要寻找一个完整的解决方案(尽管我会接受它),而是寻找关于从哪里跳入 EF 的管道以及如何做到这一点的指导。 IE。我需要考虑哪些 EF 类、配置、约定等?
- 我希望按预期生成迁移。也就是说,我不希望我的
Bar
属性 变成指向 "Bar" table 的 "Bar_Id" 字段。相反,我想要一个 nvarchar(max)
"Bar" 字段,它将包含 Bar
对象的序列化版本。如果这根本不可能,请在您的回答中说明。
备注:
- 观看 Rowan Miller 的 Building Applications with Entity Framework 6 视频后产生了这个想法。
ComplexType
不能满足我的需要。我需要深度序列化,不需要能够过滤或排序已序列化内容的任何属性。
- 我计划使用 Newtonsoft 的 JSON 库进行序列化,但序列化的方式并不重要。
不修改 EF 是不行的。
对于 EF 6,我认为有几个人使用文本支持字段和一些限制来做到这一点(Bar 和 Bar children does not access to EF persisted 属性 or you need other work after deserialization)。
唯一的解决办法是,
public class Foo
{
public Guid Id { get; set; }
// Not Mapped attribute will make EF
// ignore this property completely
[NotMapped]
public Bar BarObject {
get;
set;
}
public string Bar{
get{
return JsonConvert.Serialize(BarObject);
}
set{
BarObject = JsonConvert.Deserialize<BarObject>(value);
}
}
}
根据@zds
的建议更新
示例:假设我有这三个 类。 Foo
是一个带有 DbSet 的正确 Entity Framework 实体,而我希望我的 EF DbContext 不知道 Bar
和 Baz
因为我已经用 Foo 的 Bar 属性 标记了我组成的 SerializedColumn
属性。通过应用该属性,我希望 EF 将 Bar 的实例及其 Bazes 序列化为单个字符串字段,并在 EF 实现 Foo 时透明地将 Bar 反序列化为 Bar 对象。
public class Foo
{
public Guid Id { get; set; }
[SerializedColumn]
public Bar Bar { get; set; }
// ..
}
public class Bar
{
public string Name { get; set; }
public Baz[] Baz { get; set; }
// ..
}
public class Baz
{
public string Name { get; set; }
// ..
}
所以 Foo 的 table 列看起来像:
[Id] [uniqueidentifier] NOT NULL
[Bar] [nvarchar](max) NULL
当我查询 Foo
时,我返回一个 Bar
属性 已经反序列化的查询。当我插入或更新 Foo
时,Bar
属性 会被 EF 序列化,而我无需考虑它。我唯一需要做的就是将 [SerializeColumn]
属性添加到属性中。
目标:
- 我不一定要寻找一个完整的解决方案(尽管我会接受它),而是寻找关于从哪里跳入 EF 的管道以及如何做到这一点的指导。 IE。我需要考虑哪些 EF 类、配置、约定等?
- 我希望按预期生成迁移。也就是说,我不希望我的
Bar
属性 变成指向 "Bar" table 的 "Bar_Id" 字段。相反,我想要一个nvarchar(max)
"Bar" 字段,它将包含Bar
对象的序列化版本。如果这根本不可能,请在您的回答中说明。
备注:
- 观看 Rowan Miller 的 Building Applications with Entity Framework 6 视频后产生了这个想法。
ComplexType
不能满足我的需要。我需要深度序列化,不需要能够过滤或排序已序列化内容的任何属性。- 我计划使用 Newtonsoft 的 JSON 库进行序列化,但序列化的方式并不重要。
不修改 EF 是不行的。 对于 EF 6,我认为有几个人使用文本支持字段和一些限制来做到这一点(Bar 和 Bar children does not access to EF persisted 属性 or you need other work after deserialization)。
唯一的解决办法是,
public class Foo
{
public Guid Id { get; set; }
// Not Mapped attribute will make EF
// ignore this property completely
[NotMapped]
public Bar BarObject {
get;
set;
}
public string Bar{
get{
return JsonConvert.Serialize(BarObject);
}
set{
BarObject = JsonConvert.Deserialize<BarObject>(value);
}
}
}
根据@zds
的建议更新