简体   繁体   中英

EF Code First - Get POCO from Proxy

Question:

Is it possible when dealing with dynamic proxy to pull out the underlying POCO when we need to serialize them?

Rationale:

I have a requirement to serialize (XML) my POCO entities using EF Code First but quickly found that DbContext creates dynamic proxy for my POCO and that makes it hard to serialize.

I have tried the following:

  1. Disable proxy creation in the DbContext and work only with pure POCO. This allows me to serialize the instances any way I like. The only catch is that navigational properties are not being tracked, therefore, I must attach all related entities manually when I want to save otherwise new entities will always be created (see code example).
  2. Implement ISerializable interface on the POCO to manually handle serialization. This is a lot of work and is not a sustainable solution.

Code example.

// Attach and update tags
foreach (var tag in entity.Tags)
{
    Context.Entry(tag).State = Context.Tags.Any(t => t.ID == tag.ID)
                                    ? EntityState.Modified
                                    : EntityState.Added;
}

// Attach and update state.
Context.Entry(entity).State = Context.Resources.Any(x => x.ID == entity.ID)
                                    ? EntityState.Modified
                                    : EntityState.Added;

As you can imagine, the complexity can get out of hand when my entity have more relationships.

Is it possible when dealing with dynamic proxy to pull out the underlying POCO when we need to serialize them?

No because there is no underlying POCO - the proxy is not a wrapper around entity instance. It is entity instance directly.

You can use DataContractSerializer and ProxyDataContractResolver to serialize proxied POCOs but serializing proxied entities sounds like you are trying to serialize entities with lazy loading enabled - that can serialize much more than you expect because every property will be lazy loaded recursively until there is no single non-loaded navigation property in the whole object graph.

You must also handle circular references when using DataContractSerializer by marking your entities with [DataContract(IsReference = true)] and every serializable property with [DataMember] .

The only catch is that navigational properties are not being tracked

Entities without proxy are tracked as well. The tracking is dependent on entity being attached not entity being proxied.

I must attach all related entities manually when I want to save

You must always attach deserialized entities if you want to persist them.

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