实体条目的意外GetType()结果

Ant*_*tov 33 c# entity-framework objectstatemanager ef-code-first dbcontext

当我迭代通过ObjectStateEntries我期望[t]变量名称将是MY_ENTITY

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

但我是真实的

System.Data.Entity.DynamicProxies.MY_ENTITY_vgfg7s7wyd7c7vgvgv.....
Run Code Online (Sandbox Code Playgroud)

如何确定可以将当前条目转换为MY_ENTITY类型?

Ger*_*old 53

您可以通过获取代理类型的原始实体类型

ObjectContext.GetObjectType(entity.GetType())
Run Code Online (Sandbox Code Playgroud)

这是一种静态方法ObjectContext,因此您可以在DbContext环境中轻松使用.

如果由于某种原因您需要将实际实体作为其原始类型,则可以使用该模式

var entity = entry.Entity as MyEntity;
if (entity != null)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

这比稍微有效一点

if (entry.Entity is MyEntity)
{
    var entity = (MyEntity)entry.Entity;
    ...
}
Run Code Online (Sandbox Code Playgroud)

因为后一个片段会将对象强制转换两次.


Enr*_*tta 8

您可以使用

Type t = entry.Entity.GetType().BaseType;
Run Code Online (Sandbox Code Playgroud)

要么

ObjectContext.GetObjectType(entity.GetType())
Run Code Online (Sandbox Code Playgroud)

但从我的角度来看,这种second方式更好.如果在Mapper方法中调用Type()请求,例如DTO映射器(从实体对象到DTO类或从内存中对象到DTO类),ObjectContext.GetObjectType(..)始终为您提供与预期结果相反的预期结果.GetType().BaseType

例如,如果对EF实体模型使用TPT(每类型表)策略,则对内存中对象调用BaseType()将返回层次结构中的基类,这与ObjectContext.GetObjectType(..)

在此输入图像描述


Goo*_*ide 5

另一种方法是访问BaseType返回的代理类型的属性:

Type t = entry.Entity.GetType().BaseType;
Run Code Online (Sandbox Code Playgroud)

  • 我最初使用这个答案,因为它看起来比接受的答案更整洁(比需要ObjectContext更自给自足)。但是,根据情况,可能会出现问题。如果要添加实体,它还不是代理类型,而仅仅是POCO类型。因此,对其调用BaseType将返回“对象”。如果您仅使用代理类型,例如仅处理从数据库中检索到的实体,那么就没问题,但是如果它可能是POCO或代理,例如集合中有未保存的实体,则使用ObjectConext作为Enrico是唯一安全的选择解释如下。 (7认同)