如何从实体代理类型获取实体 POCO 类型

本文关键字:类型 实体 获取 POCO 代理 | 更新日期: 2023-09-27 17:56:10

我正在将项目从 EF6 迁移到 EF-Core。 元数据 API 发生了重大变化,我无法找到解决方案:

在EF6下,我可以使用以下方法从代理类型中找到POCO类型:

ObjectContext.GetObjectType(theEntity.GetType)

但是,这在 EF-Core 下不起作用(无ObjectContext类)。 我搜索了又搜索无济于事。 有谁知道如何从entityentity proxy type获取POCO类型?

如何从实体代理类型获取实体 POCO 类型

没有完美的方法。例如,您可以检查命名空间。如果是代理,它将

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

EF Core 不支持 ObjectContext API。此外,EF Core 没有代理类型。

您可以从 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;
    }
}
EF Core

通过 Microsoft.EntityFrameworkCore.Proxies nuget 包支持代理。因此,要解开代理类的包装,您可以使用此方法:

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;
}

使用实体框架核心ObjectContext不可用。类似于@Mariusz Jamro 答案,但没有字符串,您可以测试对象是否实现了 IProxyTargetAccessor 接口。

尽管接口公开了该方法DynProxyGetTarget但在这种情况下无法使用它,因为您再次 取回代理。相反,您必须查看基本类型,如Mariusz的答案所示。

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