简体   繁体   中英

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

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. IE 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.

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

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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM