C# ObjectContext中的EntityFramework EntityType?

C# ObjectContext中的EntityFramework EntityType?,c#,entity-framework,objectcontext,C#,Entity Framework,Objectcontext,我有一个带有此签名的方法: public void GenerateLog(TEntity实体),其中TEntity:EntityObject 如何循环我的ObjectContext并为ObjectContext中的每个实体调用它? 我知道我可以做到这一点: foreach (ObjectStateEntry entry in context.ObjectStateManager.GetObjectStateEntries( Ent

我有一个带有此签名的方法:

public void GenerateLog(TEntity实体),其中TEntity:EntityObject

如何循环我的ObjectContext并为ObjectContext中的每个实体调用它?
我知道我可以做到这一点:

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

但是我不知道如何从名称的字符串表示转到
GenerateLog
,而不是
GenerateLog

,,正如Drew Marsh所说,没有办法只使用泛型类型参数的名称调用泛型方法。正因为如此,我只能建议您使用运行时方法解析(runtime method resolution)来解决您可能认为有点垃圾的问题-尽管它会起作用

首先,在
foreach
中分配一个动态变量,并调用名为的私有方法(例如
CallGenerateLog()

…为每个要记录的实体类型提供一个重载
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)
{
}
这方面的问题包括:

  • 对于每个实体类型,您都需要一个重载
    CallGenerateLog()
    ,因此,如果您添加了一个要记录的新实体类型,您必须记住为其添加重载(尽管您可以使用T4模板解决此问题)

  • 运行时方法解析会有一些开销,因此您可能必须分析该方法的性能,并决定它是否会给您带来任何问题


  • 您需要从
    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所在的类。

    无法使用字符串调用泛型方法,您必须提供一个只接受object(或其他公共基类)的重载。GenerateLog在内部具体做什么?换句话说,为什么一开始它是通用的?你在方法体中做了什么,使它作为一个泛型方法有价值?也许有了这些知识,人们可以提供一个替代的解决方案或建议来实现你想要的。这是一种根据数据库中的记录记录更改的方法。这种张力会渗透到整个事物中。整件事都进行得很顺利…只是我在这一点上有些犹豫。如果我通过提供像GenerateLog这样的实际对象类型来调用它,那么它的工作是完美的。但是我需要调用它,而不是那样做,因为我需要调用大量的对象。为每个实体类型调用正是我想要避免的。你说的这些“T4模板”是什么?很公平,re:每种类型一次呼叫-这只是我能想到的实现你想要实现的唯一方法。T4模板是代码生成文件-实体框架使用它们生成其默认和POCO实体类源代码-您仍然可以对每种类型进行一次调用,但您可以减少忘记重载的可能性,因为代码将自动生成。天哪……这太神奇了。到目前为止,它工作得很好!我还没有检查您的答案,因为我不能100%确定这是我的解决方案,因为我必须先修复其他错误:到目前为止,它看起来很完美。史蒂夫,这是一个绝妙的解决方案。很好@James这是我第一次使用MakeGenericMethod时的反应,那是在不久前。它很方便。这样做的代价是,它比使用带有强类型调用的大型case语句或类似语句要慢。
    MethodInfo generateLog = typeof(YourClass)
        .GetMethod("GenerateLog", BindingFlags.Public | BindingFlags.Instance );
    
    MethodInfo genericGenerateLog = generateLog.MakeGenericMethod(entry.Entity.GetType());
    
    genericGenerateLog.Invoke(this, new object[] { entry.Entity });