使用实体框架将集合另存为JSON

rle*_*ler 8 .net c# sql json entity-framework

我试图找到一种方法来获得一个集合的对象,但当它保存到数据库时成为一个JSON字符串.我如何设置实体框架6.1来做到这一点?例:

 public class Company{

    public Company(){
       this.Times = new HashSet<DateTime>();
    }

    public int Id {get;set;}

    public string Name {get;set;}

    public List<DateTime> Times {get;set;}

 }
Run Code Online (Sandbox Code Playgroud)

公司是一个实体对象.我希望Times能够作为json字符串存储在数据库中.我希望它在从数据库中读取时作为日期时间列表进行序列化.我想将保存列表转换回json字符串并保存.

Mat*_*ins 13

接受的答案的问题是EF 不会跟踪列表内容的任何更改(添加,修改或删除条目).

这是我的解决方案,受到这篇优秀博客文章的启发.

此类负责序列化和反序列化,以便集合可以存储在父模型的单个列中:

[ComplexType]
public class DateTimeCollection : Collection<DateTime>
{
    public void AddRange(IEnumerable<DateTime> collection)
    {
        foreach (var item in collection)
        {
            Add(item);
        }
    }

    [Column("Times")]
    public string Serialized
    {
        get { return JsonConvert.SerializeObject(this); }
        private set
        {
            if (string.IsNullOrEmpty(value))
            {
                Clear();
                return;
            }

            var items = JsonConvert.DeserializeObject<DateTime[]>(value);
            Clear();
            AddRange(items);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

而已!您现在可以完全按照您的期望在父类上使用此新集合.将跟踪对集合内容的更改.

public class Company{
    // ...
    public DateTimeCollection Times { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

  • 很棒的答案.值得包括在`DBCotext`中定义ComplexType的方式.as:`modelBuilder.ComplexType <DateTimeCollection>().Property(p => p.Serialized).HasColumnName("Times");` (5认同)

Dix*_*onD 5

以下应该工作(我使用Json.Net,但您可以将其更改为任何其他序列化程序):

public class Company
{

    public int Id {get;set;}

    public string Name {get;set;}

    [NotMapped]
    public List<DateTime> Times {get;set;}

    [Column("Times")]
    public string TimesSerialized
    {
        get
        {
            return JsonConvert.SerializeObject(Times);
        }
        set
        {
            Times = string.IsNullOrEmpty(value)
                    ? new List<DateTime>()
                    : JsonConvert.DeserializeObject<List<DateTime>>(value);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果手动映射,也可以将TimesSerialized设为私有.