2012-02-14 36 views
5

鑑於實體框架4.0的代碼第一個實體如何在連接到DBContext之前通過屬性單獨檢索EF 4代碼第一個實體的[Key]?

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

有沒有一種方法來檢索不知道屬性的名稱飾以[鍵]屬性的屬性值?

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

UPDATE

我有一個的DbContext,這樣我就可以使用下面的代碼:

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

然而,實體後,這僅適用於已添加或連接到的DbContext 。問題是我想使用動態知識的關鍵和它的價值來確定是否應該執行插入或更新,因此是否添加或附加到上下文。在這個代碼變得可能的時候,這太遲了。

我已編輯問題標題以反映此問題。

還有什麼想法?

回答

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 

注意,此方法將只返回第一個屬性的值用KeyAttribute裝飾,並且如果找不到Key屬性將返回null。

3

如果您有ObjectContext您的實體是其中一員,您可以撥打YourContext.GetObjectStateEntry(entity)。這將返回一個對應的ObjectStateEntry對象,其中包含一個存儲關鍵值的EntityKey屬性。

如果您使用的是DbContext,我沒有看到類似的功能。但是,即使它沒有,仍然可以使用IObjectContextAdapter((IObjectContextAdapter)YourContext).ObjectContext)獲取底層的ObjectContext,然後使用上述內容。

+0

這是正確的,但看到我的更新,爲什麼這是無助於解決潛在的意圖。無論如何,我都投了贊成票,因爲我很欣賞這個建議。 – 2012-02-15 18:38:58

+0

你*可以*附加它,使用它來獲得鍵值,如果你看到你應該添加它,調用'ObjectStateEntry.ChangeState(EntityState.Added)'。但是,真的,首先做錯了事,檢查你是否做錯了,然後修復它。你接受的答案可能是一個更好的主意。 – hvd 2012-02-15 19:09:44

相關問題