我有一个带有此签名的方法:
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 :(得分: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所在的类。
答案 1 :(得分:-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);
}
... etc ...并提供一个catch-all重载,它将满足编译器并在找到没有显式重载的实体类型时被调用。
private static void CallGenerateLog(object entity)
{
}
问题包括:
您需要为每个实体类型重载CallGenerateLog()
,因此如果您添加要记录的新实体类型,则必须记住为其添加重载(尽管您可以用T4模板解决这个问题)
运行时方法解析有一些开销,因此您可能需要分析该方法的执行情况,并确定它是否会导致任何问题。