2011-05-27 85 views
0

我有這個簽名的方法:ObjectContext的EntityFramework EntityType?

public void GenerateLog<TEntity>(TEntity entity) where TEntity : EntityObject

我如何遍歷我ObjectContext的,在我的ObjectContext調用此爲每個實體?
我知道我能做到這一點:

foreach (ObjectStateEntry entry in 
       context.ObjectStateManager.GetObjectStateEntries(
       EntityState.Added | EntityState.Modified)) 
{ 
    string entityName = entry.Entity.GetType().Name; 
} 

但我不知道如何從名稱的字符串表示去GenerateLog<MYSTRING>,而不是GenerateLog<TEntity>

+0

有沒有辦法來調用一個泛型方法用一個字符串,你必須提供一個只需要對象(或其他公共基類)的重載。 GenerateLog在內部做了什麼?換句話說,爲什麼一開始就是通用的?你在這個方法的主體中做了什麼,它有一個通用的方法是有價值的?也許有了這些知識,人們可以提供一個替代解決方案或建議如何實現你想要的。 – 2011-05-27 23:54:59

+0

這是一種記錄數據庫記錄更改的方法。 TEntity過濾整個事情。整個事情都在奇妙地發揮着作用,除了我在這一點上掛了。如果我通過提供像GenerateLog 這樣的實際對象類型來調用它,它可以完美地工作。但是我需要不這樣做,因爲有些東西我不得不稱之爲。 – 2011-05-27 23:58:07

回答

2

您需要從您的GenerateLog製作一個通用方法,然後調用該方法。我通常需要浪費時間有點之前,我得到這樣的工作,但是這應該是接近

MethodInfo generateLog = typeof(YourClass) 
    .GetMethod("GenerateLog", BindingFlags.Public | BindingFlags.Instance); 

MethodInfo genericGenerateLog = generateLog.MakeGenericMethod(entry.Entity.GetType()); 

genericGenerateLog.Invoke(this, new object[] { entry.Entity }); 

YourClass簡直是班上GenerateLog是英寸

+0

神聖的地獄....那太神奇了。到目前爲止,它的工作非常完美!我還沒有檢查過你的答案,因爲我不是100%確定它是我的解決方案,因爲我必須先解決其他錯誤。 :P到目前爲止,它看起來很完美。 – 2011-05-28 01:50:37

+0

傑出的解決方案史蒂夫。很棒! – 2011-05-28 01:54:05

+0

@詹姆斯當我第一次使用MakeGenericMethod時,這是我的反應,它不是很久以前。這非常方便。權衡是,它比如果你有一個強類型的呼叫或沿着這些線路的巨大的case語句慢。 – 2011-05-28 17:24:09

-1

正如Drew Marsh所說,沒有辦法只用泛型Type參數的名稱來調用泛型方法。因此,我只能建議你可能會認爲使用運行時方法的解決方案是一個垃圾解決方案 - 儘管它會工作...

首先,在foreach內分配一個動態變量,然後調用命名的私有方法(例如)CallGenerateLog()

foreach (ObjectStateEntry entry in 
       context.ObjectStateManager.GetObjectStateEntries(
       EntityState.Added | EntityState.Modified)) 
{ 
    dynamic dynamicEntity = entry.Entity; 

    CallGenerateLog(dynamicEntity); 
} 

...每個要登錄的實體類型的提供CallGenerateLog()一個過載,並有每一個打電話給你的GenerateLog()方法,如:

private static void CallGenerateLog(User user) 
{ 
    GenerateLog(user); 
} 

private static void CallGenerateLog(Customer customer) 
{ 
    GenerateLog(customer); 
} 

...等等,並提供一個滿足編譯器的catch-all超載,並且如果找到的實體類型沒有顯式超載,則會被調用。

這個
private static void CallGenerateLog(object entity) 
{ 
} 

的問題包括:

  1. 你需要的CallGenerateLog()爲每個實體類型的過載,因此,如果您添加要記錄一個新的實體類型,你必須記住添加一個過載(雖然你可以用T4模板解決這個問題)

  2. 運行時方法解析有一些開銷,所以你可能必須剖析方法執行的方式,並決定它是否會給你帶來任何問題。

+0

爲每個實體類型打電話正是我想要避免的。你說的這些「T4模板」是什麼? – 2011-05-28 00:41:11

+0

足夠公平,重新:每種類型一個電話 - 這是我能想到的唯一方法。 T4模板是代碼生成文件 - 實體框架使用它們來生成其默認和POCO實體類源代碼 - 您仍然在爲每個類型進行一次調用,但是可以減少您忘記重載的機會,因爲代碼會自動生成。 – 2011-05-28 00:48:15