2011-05-27 73 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