给定一个实体框架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
,然后使用上面的。