Sam Axe
Sam Axe

Reputation: 33738

How to get the Entity POCO type from the Entity Proxy type?

I'm migrating a project from EF6 to EF-Core. The Metadata API has changed significantly and I am unable to find a solution to this:

Under EF6 I could find the POCO Type from the Proxy Type using:

ObjectContext.GetObjectType(theEntity.GetType)

This, however, does not work under EF-Core (no ObjectContext class). I've searched and searched to no avail. Does anyone know how to get the POCO type from either the entity or the entity proxy type?

Upvotes: 6

Views: 3523

Answers (4)

Pavel Korsukov
Pavel Korsukov

Reputation: 959

EF Core supports proxies via Microsoft.EntityFrameworkCore.Proxies nuget package. So, to unwrap the proxy class you can use this approach:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;

....

public static Type GetEntityType(DbContext context, object entity)
{
    if(entity == null || context == null){
        throw new ArgumentNullException();
    }

    return context.Model.FindRuntimeEntityType(entity.GetType()).ClrType;
}

Upvotes: 2

Bronumski
Bronumski

Reputation: 14272

With Entity Framework Core ObjectContext is not available. Similar to @Mariusz Jamro answer but without the string you can test if the object implements the IProxyTargetAccessor interface.

Although the interface exposes the method DynProxyGetTarget it cannot be used in this instance because you get back the proxy again 🤯. Instead you have to look at the base type as demonstrated in the Mariusz's answer.

private Type UnProxy<T>(T entity) => entity switch
{
  null => typeof(T),
  IProxyTargetAccessor proxy => proxy.GetType().BaseType,
  var e => e.GetType()
};

Upvotes: 0

Mariusz Jamro
Mariusz Jamro

Reputation: 31633

There is no perfect way. You could for example check the namespace. If it's a proxy it'll

private Type Unproxy(Type type)
{
    if(type.Namespace == "Castle.Proxies")
    {
        return type.BaseType;
    }
    return type;
}

Upvotes: 9

natemcmaster
natemcmaster

Reputation: 26763

EF Core does not support the ObjectContext API. Further more, EF Core doesn't have proxy types.

You can get metadata about entity types from IModel.

using (var db = new MyDbContext())
{
    // gets the metadata about all entity types
    IEnumerable<IEntityType> entityTypes = db.Model.GetEntityTypes();

    foreach (var entityType in entityTypes)
    {
        Type pocoType = entityType.ClrType;
    }
}

Upvotes: 4

Related Questions