Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save Collection As JSON with Entity Framework

I am trying to find a way to have an object that is a colleciton but when it is saved to the database becomes a JSON string. How can i set up entity framework 6.1 to do this? Example:

 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;}

 }

Company is an entity object. I would like for Times to be stored in the database as a json string of times. I would like it to serialize when reading from the database as a list of date time. I would like the list on save to be converted back to the json string and saved.

like image 529
rleffler Avatar asked Feb 03 '15 19:02

rleffler


2 Answers

The problem with the accepted answer is that any changes to the contents of the list (adding, modifying or deleting entries) won't be tracked by EF.

Here is my solution, inspired by this excellent blog post.

This class takes care of serializing and deserializing so that the collection can be stored in a single column on the parent model:

[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);
        }
    }
}

That's it! You can now use this new collection on your parent class exactly as you'd expect. Changes to the contents of the collection will be tracked.

public class Company{
    // ...
    public DateTimeCollection Times { get; set; }
}
like image 111
Matt Jenkins Avatar answered Oct 23 '22 02:10

Matt Jenkins


The following should work (I used Json.Net, but you can change it to any other serializer):

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);
        }
    }
}

You can also make TimesSerialized private if you map it manually.

like image 6
DixonD Avatar answered Oct 23 '22 02:10

DixonD