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

Ada*_*ynn 5 c# entity-framework entity-framework-4 ef-code-first

给定一个实体框架4.0代码第一个实体

public class MyEntity
{
  [Key]
  public int MyEntityId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

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

UPDATE

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

var objectContext = ((IObjectContextAdapter) myContext).ObjectContext;
objectContext.ObjectStateManager.GetObjectStateEntry(entity).EntityKey.EntityKeyValues;
Run Code Online (Sandbox Code Playgroud)

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

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

有进一步的想法?

Roc*_*oC5 7

另一种可能的解决方案是使用反射来查找用属性修饰的[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
Run Code Online (Sandbox Code Playgroud)

请注意,此方法仅返回使用KeyAttribute修饰的第一个属性的值,如果未找到Key属性,则返回null.