Persisting and retrieving serialized entity property with Entity Framework 6.1 code first

ef-code-first ef-migrations entity-framework entity-framework-6 entity-framework-6.1

Question

Example: Let's say I have these three classes. Foo is a proper Entity Framework entity with a DbSet whereas I want my EF DbContext to be unaware of Bar and Baz because I have flagged Foo's Bar property with my made up SerializedColumn attribute. By applying that attribute, I want EF to serialize the instance of Bar with its Bazes into a single string field, and transparently deserialize Bar to a Bar object when a Foo is materialized by EF.

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

So Foo's table columns would look like:

[Id] [uniqueidentifier] NOT NULL
[Bar] [nvarchar](max) NULL

And when I query a Foo I get back one with the Bar property already deserialized. When I insert or update a Foo the Bar property gets serialized by EF without me having to think about it. The only thing I have to do is add the [SerializeColumn] attribute to properties.

Goals:

  • I'm not necessarily looking for a full blown solution (although I would accept it) but for guidance on where to jump into EF's pipeline, and how to do that. I.E. what EF classes, configurations, conventions, etc. do I need to take into account?
  • I want Migrations to be generated as one would expect. Which is to say, I wouldn't want my Bar property to turn into a "Bar_Id" field that points to a "Bar" table. Instead I want a nvarchar(max) "Bar" field that will contain the serialized version of a Bar object. If this simply isn't possible, please say so in your answer.

Notes:

  • The idea for this came after watching the Building Applications with Entity Framework 6 video by Rowan Miller.
  • ComplexType does not serve my needs. I need deep serialization and do not need to be able to filter or sort on any properties of what has been serialized.
  • I plan on serializing with Newtonsoft's JSON library, but how serialization happens doesn't really matter.
1
7
12/1/2015 5:19:04 PM

Accepted Answer

The only solution is this,

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

Updated as per suggestion by @zds

10
8/3/2016 4:26:57 PM

Popular Answer

No way to do it without modifing EF. With EF 6 I think that several people did it with a text backing field and some limitations (Bar and Bar children does not access to EF persisted property or you need other work after deserialization).



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow