unexpected GetType() result for entity entry
Asked Answered
C

3

35

While I iterating through ObjectStateEntries I expected [t] variable name will be MY_ENTITY

foreach (ObjectStateEntry entry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Deleted))
{
    Type t = entry.Entity.GetType();
    ...
}

but real I have

System.Data.Entity.DynamicProxies.MY_ENTITY_vgfg7s7wyd7c7vgvgv.....

How can I determine can I cast current entry to MY_ENTITY type?

Corps answered 14/4, 2013 at 21:44 Comment(1)
Have you tried to compare using the is keyword?Dunsinane
L
57

You can get the original entity type of a proxy type by

ObjectContext.GetObjectType(entity.GetType())

This is a static method of ObjectContext, so you can readily use in in a DbContext environment.

If for some reason you need the actual entity as its original type you can use the pattern

var entity = entry.Entity as MyEntity;
if (entity != null)
{
    ...
}

This is slightly more efficient than

if (entry.Entity is MyEntity)
{
    var entity = (MyEntity)entry.Entity;
    ...
}

because the latter snippet casts the object twice.

Leucine answered 14/4, 2013 at 22:58 Comment(3)
A very good reason for needing to know the original type is for overriding Equals(), as the standard GetType() returns the proxy, which is not the same as the underlying type.Raffish
The (should have been) obvious fact that the method is static was completely lost on me until you pointed it out!Zehe
Of course, now you can do if (entry.Entity is myEntity entity) { ... } which will declare and assign entityMerganser
C
10

You can use

Type t = entry.Entity.GetType().BaseType;

or

ObjectContext.GetObjectType(entity.GetType())

But the second way is a better way from my point of view. If you call Type() request inside a Mapper method, for example DTO mapper (from entity object to DTO class or from in-memory objects to DTO class), ObjectContext.GetObjectType(..) will grant you always the expected result contrary to what will .GetType().BaseType

For example, if you use a TPT (Table per Type) strategy for EF Entity Model, call BaseType() on in-memory object will return the base class in hierarchy contrary to what will ObjectContext.GetObjectType(..)

enter image description here

Campman answered 4/7, 2015 at 8:53 Comment(0)
K
5

Another way is to access the BaseType property of the returned proxy type:

Type t = entry.Entity.GetType().BaseType;
Kalat answered 9/4, 2015 at 12:4 Comment(1)
I initially went with this answer as it looks neater (more self contained than needing ObjectContext around) than the accepted answer. However, there is a potential problem depending on the scenario. If you are adding an entity, it's not a proxy type yet, but just a POCO type. Therefore, calling BaseType on it returns 'object'. If you are only working with proxy types, such as if it's just dealing with entities retrieved from DB then no problem, but if it could be POCO or proxy, such as if collection has unsaved entities, using ObjectConext is the only safe option as Enrico explains below.Eudo

© 2022 - 2024 — McMap. All rights reserved.