在附加到 DBContext 之前,如何仅通过属性检索 EF 4 代码第一个实体的 [键]?



给定一个实体框架4.0代码优先的实体

public class MyEntity
{
  [Key]
  public int MyEntityId { get; set; }
}

有没有一种方法可以在不知道属性名称的情况下检索用[Key]属性修饰的属性的值?

public class KeyReader<TEntity> : where TEntity : class
{
  public int GetKeyValue(TEntity entity){
    //get key value for entity
  }
}

更新

我有一个DBContext,所以我可以使用以下代码:

var objectContext = ((IObjectContextAdapter) myContext).ObjectContext;
objectContext.ObjectStateManager.GetObjectStateEntry(entity).EntityKey.EntityKeyValues;

但是,只有在将实体添加或附加到DBContext之后,这才有效。问题是,我想使用密钥及其值的动态知识来确定是否应该执行插入或更新,从而决定是否将其添加或附加到上下文中。当这个代码成为可能时,已经太晚了。

我编辑了问题标题以反映这一点。

还有什么想法吗?

另一种可能的解决方案是使用反射来查找用[Key]属性修饰的属性,并返回其值:

private object GetKeyValue<T>(T entity) where T : class
{
    PropertyInfo key =
        typeof(T)
        .GetProperties()
        .FirstOrDefault(p => p.GetCustomAttributes(typeof(KeyAttribute), true).Length != 0);
    return key != null ? key.GetValue(entity, null) : null;
}
MyEntity instanceOfMyEntity = new MyEntity { MyEntityId = 999; };
object keyValue = GetKeyValue<MyEntity>(instanceOfMyEntity); // keyValue == 999

请注意,此方法只返回用KeyAttribute修饰的第一个属性的值,如果找不到Key属性,则返回null。

如果您有实体所属的ObjectContext,则可以调用YourContext.GetObjectStateEntry(entity)。这将返回一个相应的ObjectStateEntry对象,该对象包含一个存储键值的EntityKey属性。

如果您使用DbContext,我看不到类似的函数。但是,即使它没有,您仍然可以使用IObjectContextAdapter((IObjectContextAdapter)YourContext).ObjectContext)来获得底层ObjectContext,然后使用上面的。

相关内容

最新更新