Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过反射访问/执行泛型方法?_C#_Entity Framework_Generics_Reflection - Fatal编程技术网

C# 通过反射访问/执行泛型方法?

C# 通过反射访问/执行泛型方法?,c#,entity-framework,generics,reflection,C#,Entity Framework,Generics,Reflection,当使用EF6时,我试图在运行时动态切换表注释的模式值 到目前为止,我得到的是: var builder = new DbModelBuilder() var dbSetProperties = typeof(T).GetProperties().Where(p => p.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>)); foreach (PropertyInfo property in dbSetProp

当使用EF6时,我试图在运行时动态切换表注释的模式值

到目前为止,我得到的是:

var builder = new DbModelBuilder()
var dbSetProperties = typeof(T).GetProperties().Where(p => p.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>));

foreach (PropertyInfo property in dbSetProperties)
{
    Type[] propTypes = property.PropertyType.GetGenericArguments();

    // Iterate the DbSets and set the correct schema
    foreach (Type dbSetType in propTypes)
    {
        // Get the TableAttribute
        var tableAttribute = Attribute.GetCustomAttribute(dbSetType, typeof(TableAttribute));

        MethodInfo dbModelMethodInfo = typeof(DbModelBuilder).GetMethod("Entity");
        MethodInfo entityTypeConfigMethodInfo = typeof(EntityTypeConfiguration<>).GetMethod("ToTable", new[] { typeof(String), typeof(String) });
        MethodInfo genericDbModelMethodInfo = dbModelMethodInfo.MakeGenericMethod(dbSetType);

        genericDbModelMethodInfo.Invoke(builder, null);
        entityTypeConfigMethodInfo.Invoke(genericDbModelMethodInfo, new Object[] { (tableAttribute as TableAttribute).Name, "NEW_SCHEMA_VALUE" });
    }
}
var builder=new DbModelBuilder()
var dbSetProperties=typeof(T).GetProperties(),其中(p=>p.PropertyType.GetGenericTypeDefinition()==typeof(DbSet));
foreach(dbSetProperties中的PropertyInfo属性)
{
Type[]propTypes=property.PropertyType.GetGenericArguments();
//迭代数据库集并设置正确的模式
foreach(在propTypes中键入dbSetType)
{
//获取table属性
var tableAttribute=Attribute.GetCustomAttribute(dbSetType,typeof(tableAttribute));
MethodInfo dbModelMethodInfo=typeof(DbModelBuilder).GetMethod(“实体”);
MethodInfo entityTypeConfigMethodInfo=typeof(EntityTypeConfiguration).GetMethod(“ToTable”,新[]{typeof(String),typeof(String)});
MethodInfo genericDbModelMethodInfo=dbModelMethodInfo.MakeGenericMethod(dbSetType);
Invoke(builder,null);
entityTypeConfigMethodInfo.Invoke(genericDbModelMethodInfo,新对象[]{(tableAttribute作为tableAttribute).Name,“new_SCHEMA_VALUE”});
}
}
我试图完成的是这样的事情(这是行不通的):

builder.Entity();
基本上,对于T,我想提取数据库集,确定实体泛型中使用的类,获取TableAttribute,并将模式设置为新值

目前,在entityTypeConfigMethodInfo.Invoke上,我得到一个错误“不能对ContainsGenericParameters为true的类型或方法执行后期绑定操作”


我错过了什么?

嗯,是的,你期待什么

您说您在这一行中得到了错误:

entityTypeConfigMethodInfo.Invoke(genericDbModelMethodInfo, new Object[] { (tableAttribute as TableAttribute).Name, "NEW_SCHEMA_VALUE" });
MethodInfo entityTypeConfigMethodInfo = typeof(EntityTypeConfiguration<>).GetMethod("ToTable", new[] { typeof(String), typeof(String) });
问题不在于这一行,而在于这一行:

entityTypeConfigMethodInfo.Invoke(genericDbModelMethodInfo, new Object[] { (tableAttribute as TableAttribute).Name, "NEW_SCHEMA_VALUE" });
MethodInfo entityTypeConfigMethodInfo = typeof(EntityTypeConfiguration<>).GetMethod("ToTable", new[] { typeof(String), typeof(String) });

嗯,是的,你期待什么

您说您在这一行中得到了错误:

entityTypeConfigMethodInfo.Invoke(genericDbModelMethodInfo, new Object[] { (tableAttribute as TableAttribute).Name, "NEW_SCHEMA_VALUE" });
MethodInfo entityTypeConfigMethodInfo = typeof(EntityTypeConfiguration<>).GetMethod("ToTable", new[] { typeof(String), typeof(String) });
问题不在于这一行,而在于这一行:

entityTypeConfigMethodInfo.Invoke(genericDbModelMethodInfo, new Object[] { (tableAttribute as TableAttribute).Name, "NEW_SCHEMA_VALUE" });
MethodInfo entityTypeConfigMethodInfo = typeof(EntityTypeConfiguration<>).GetMethod("ToTable", new[] { typeof(String), typeof(String) });

要为第二次调用获取正确的关闭泛型methodinfo,请将代码重写为:

MethodInfo genericDbModelMethodInfo = dbModelMethodInfo.MakeGenericMethod(dbSetType);
MethodInfo entityTypeConfigMethodInfo = genericDbModelMethodInfo.ReturnType.GetMethod("ToTable", new[] { typeof(String), typeof(String) });
然后必须使用
genericdmodelmethodinfo.Invoke
调用的返回值作为第二个调用中的第一个参数

var obj = genericDbModelMethodInfo.Invoke(builder, null);
entityTypeConfigMethodInfo.Invoke(obj, new Object[] { (tableAttribute as TableAttribute).Name, "NEW_SCHEMA_VALUE" });

这是因为
MethodInfo.Invoke
中的第一个参数是要在其上调用该方法的对象。

要为重写代码的第二次调用获取正确的关闭的通用MethodInfo,请执行以下操作:

MethodInfo genericDbModelMethodInfo = dbModelMethodInfo.MakeGenericMethod(dbSetType);
MethodInfo entityTypeConfigMethodInfo = genericDbModelMethodInfo.ReturnType.GetMethod("ToTable", new[] { typeof(String), typeof(String) });
然后必须使用
genericdmodelmethodinfo.Invoke
调用的返回值作为第二个调用中的第一个参数

var obj = genericDbModelMethodInfo.Invoke(builder, null);
entityTypeConfigMethodInfo.Invoke(obj, new Object[] { (tableAttribute as TableAttribute).Name, "NEW_SCHEMA_VALUE" });

这是因为
MethodInfo.Invoke
中的第一个参数是要在其上调用方法的对象。

由于EntityTypeConfiguration是泛型类型,您能否为EntityTypeConfiguration指定对象中使用的泛型参数类型。 例:

Type Type=typeof(GenericClass)。MakeGenericType(typeof(int));
这里的“GenericClass”是一个带有泛型“T”参数的泛型类。 我在获取它的类型信息时指定了int type。 然后对该类型调用该方法将正常工作

我已经编写了一个示例代码,它也做了同样的事情,但只是尽量减少了您试图做的事情,并可能帮助您解决错误

 class Program
{
    static void Main()
    {

        Type type= typeof (GenericClass<>).MakeGenericType(typeof(int));

        var method = type.GetMethod("TestMethod");

        var instance = Activator.CreateInstance(type);


        method.Invoke(instance, null); 

    }
}

public class GenericClass<T> where T : struct // These parameters can be anything
{
    public T TestMethod()
    {
        T a = new T();

        return a; 
    }
}
类程序
{
静态void Main()
{
Type Type=typeof(GenericClass).MakeGenericType(typeof(int));
var method=type.GetMethod(“TestMethod”);
var instance=Activator.CreateInstance(类型);
调用(实例,null);
}
}
公共类GenericClass,其中T:struct//这些参数可以是任何内容
{
公共测试方法()
{
T a=新的T();
返回a;
}
}

由于EntityTypeConfiguration是泛型类型,您能否为EntityTypeConfiguration指定对象中使用的泛型参数类型。 例:

Type Type=typeof(GenericClass)。MakeGenericType(typeof(int));
这里的“GenericClass”是一个带有泛型“T”参数的泛型类。 我在获取它的类型信息时指定了int type。 然后对该类型调用该方法将正常工作

我已经编写了一个示例代码,它也做了同样的事情,但只是尽量减少了您试图做的事情,并可能帮助您解决错误

 class Program
{
    static void Main()
    {

        Type type= typeof (GenericClass<>).MakeGenericType(typeof(int));

        var method = type.GetMethod("TestMethod");

        var instance = Activator.CreateInstance(type);


        method.Invoke(instance, null); 

    }
}

public class GenericClass<T> where T : struct // These parameters can be anything
{
    public T TestMethod()
    {
        T a = new T();

        return a; 
    }
}
类程序
{
静态void Main()
{
Type Type=typeof(GenericClass).MakeGenericType(typeof(int));
var method=type.GetMethod(“TestMethod”);
var instance=Activator.CreateInstance(类型);
调用(实例,null);
}
}
公共类GenericClass,其中T:struct//这些参数可以是任何内容
{
公共测试方法()
{
T a=新的T();
返回a;
}
}

Invoke(genericDbModelMethodInfo
没有感觉到Invoke会出现同样的错误(builder——这是我第一次尝试:)dbSetType是如何定义的?我完全忘记了内部循环-更新的OP来反映(哈哈)这是因为它仍然是一个开放泛型,您检索了一个开放泛型类型的方法。您无法调用它。您必须获取特定类型的方法,因此您需要类似于
MethodInfo entityTypeConfigMethodInfo=typeof(EntityTypeConfiguration)。MakeGenericType(typeof(string)).GetMethod(…)
invoke的内容(genericDbModelMethodInfo
不会让任何人感觉到调用时会出现相同的错误(构建器——这是我第一次尝试:)dbSetType是如何定义的?我完全忘记了内部循环-更新OP以反映(哈哈)这是因为它仍然是一个开放泛型,您检索了开放泛型类型的方法。您无法调用它。您必须获取特定类型的方法,因此您需要类似于
MethodInfo entityTypeConfigMethodInfo=typeof(EntityTypeConfiguration)。MakeGeneri