Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get underlying entity object from entity framework proxy

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 
like image 707
Rich Avatar asked Sep 10 '14 16:09

Rich


People also ask

What is a proxy entity in Entity Framework?

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.

How do I find the entity type of a proxy type?

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.

How do I get the entity type of an object type?

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

Why Entity Framework does not create proxie instances for sealed types?

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.


2 Answers

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

like image 137
Ajay Bhingare Avatar answered Oct 05 '22 08:10

Ajay Bhingare


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.

like image 25
Gert Arnold Avatar answered Oct 05 '22 08:10

Gert Arnold