I have an entity by getting it from DbEntityEntry.Entity
. This returns the Entity Framework proxy for the entity.
How do I access the underlying object as its original type instead of the proxy?
Alternatively I need to dynamically try to cast the proxy to the entity type. Here's a start.
var theEntityType = entityEntry.Entity; if ( theEntityType.BaseType != null && entityType.Namespace == "System.Data.Entity.DynamicProxies" ) theEntityType = entityType.BaseType; // Now I need to cast to the correct type // THIS WON'T WORK BECAUSE `theEntityType` is dynamic. var entityObject = (theEntityType)entityEntry.Entity; // My entites also don't implement IConvertible
Working with proxies. When creating instances of POCO entity types, Entity Framework often creates instances of a dynamically generated derived type that acts as a proxy for the entity. This proxy overrides some virtual properties of the entity to insert hooks for performing actions automatically when the property is accessed.
You can find the entity type for this proxy type using the GetObjectType method from ObjectContext. For example: Note that if the type passed to GetObjectType is an instance of an entity type that is not a proxy type then the type of entity is still returned.
var emType = System.Data.Entity.Core.Objects. ObjectContext.GetObjectType (em.GetType ()); The GetObjectType returns an actual entity type even if we pass the instance of entity type (not the proxy type).
Entity Framework does not create proxie instances for the type where there is nothing to do with a proxy. It means that we can avoid creating proxies for the type that are sealed or that have no virtual properties.
While working with EF 6 i used the following code to get the underlying POCO entity type from proxy type,
var entityType = ObjectContext.GetObjectType(dbEntitymodifiedEntry.Entity.GetType());
ObjectContext.GetObjectType
: Return the POCO from proxy object
reference : https://docs.microsoft.com/en-us/ef/ef6/fundamentals/proxies
First I should say there is no underlying object. A proxy doesn't wrap an entity object (decorator pattern), it derives from it (inheritance). So we can't unwrap the entity, we can only convert a proxy to a base object. Conversion (contrary to casting) always creates a new object.
For this conversion, we can exploit the fact that most of the time, by the way proxies are returned by EF, the compile time type of a proxy is the base type. That is, if a proxy is entered as an argument to a generic method, the generic parameter will be inferred as the base type. This feature allows us to create a method that does what you want:
T UnProxy<T>(DbContext context, T proxyObject) where T : class { var proxyCreationEnabled = context.Configuration.ProxyCreationEnabled; try { context.Configuration.ProxyCreationEnabled = false; T poco = context.Entry(proxyObject).CurrentValues.ToObject() as T; return poco; } finally { context.Configuration.ProxyCreationEnabled = proxyCreationEnabled; } }
Explanation
The proxy object enters the method. Its type is inferred as the base POCO type. Now we can temporarily turn off ProxyCreationEnabled
on the context and copy the proxy object to an object of its base POCO type. This copy action gratefully uses a few EF features.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With