我有一个类,我想保留元数据 - 有几个交互场景,所以meta允许我为不同的交互类型保留不同的元数据。
class Feed()
{
Guid FeedId { get; set; }
ObjectMetaDictionary Meta { get; set; }
}
我希望EF能够序列化这个ObjectMetaDictionary并将其作为字符串/ VarChar存储在数据库中。当我检索一条记录时,我希望它被反序列化为ObjectMetaDictionary。
EF是否支持此功能?我该怎么办?
我正在使用Entity Framework Code First。
已解决:我在下方提供了一个解决了我的问题的答案。一旦SO允许我,我会接受这个答案。
答案 0 :(得分:23)
显然这实际上非常简单。由于之前的SO answer提供了一些帮助,我能够让它工作。
OnModelCreating
中的Fluent配置允许我们告诉EF使用什么作为序列化到DB的值属性并再次退出。
这是我的解决方案:
public class Feed
{
public virtual Guid FeedId { get; set; }
public virtual FeedMetaData Meta { get; set; }
public virtual string Title { get; set; }
public virtual string Description { get; set; }
}
public class FeedMetaData
{
public Dictionary<string, string> Data { get; set; }
public string Serialized
{
get { return JsonConvert.SerializeObject(Data); }
set
{
if(string.IsNullOrEmpty(value)) return;
var metaData = JsonConvert.DeserializeObject<Dictionary<string, string>>(value);
Data = metaData ?? new Dictionary<string, string>();
}
}
// addl code removed...
}
public class FeedsDbContext : DbContext
{
public DbSet<Feed> Feeds { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.ComplexType<FeedMetaData>()
.Property(p => p.Serialized)
.HasColumnName("Meta");
modelBuilder.ComplexType<FeedMetaData>().Ignore(p => p.Data);
base.OnModelCreating(modelBuilder);
}
}
答案 1 :(得分:1)
让您的Entity Framework对象简单,并为数据库中的列提供String属性。
class Feed()
{
Guid FeedId { get; set; }
String Meta { get; set; }
}
创建保存和加载属性的方法:(因为我已经使用了EF,所以我已经有一段时间了,所以我不确定你是否可以用这些getter创建一个瞬态属性/ setters或者如果你需要别的东西)
//Reading from string column Meta
(ObjectMetaDictionary) XamlServices.Load(new StringReader(someFeed.Meta));
//Saving to string column Meta
someFeed.Meta = XamlServices.Save(value);
这给你的项目带来了另一个问题。更改ObjectMetaDictionary
可能会导致它无法正确地从数据库反序列化。您的ObjectMetaDictionary
基本上成为数据库架构的一部分,您需要相应地处理版本控制或更改。
答案 2 :(得分:0)
HasConversion功能挽救了我的生命。解锁所有json格式!享受吧!
public partial class Feed
{
public int Id { get; set; }
//this column will be mapped to a "nvarchar(max)" column. perfect!
public Dictionary<string, string> Meta { get; set; }
}
public class FeedsDbContext : DbContext
{
public FeedsDbContext(DbContextOptions<FeedsDbContext> options)
: base(options)
{
}
public virtual DbSet<Feed> Feed { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Feed>(entity =>
{
entity.Property(p => p.Meta).HasConversion(
x => JsonConvert.SerializeObject(x) //convert TO a json string
, x => JsonConvert.DeserializeObject<Dictionary<string, string>>(x) //convert FROM a json string
);
});
}
}