C# 通过反射访问/执行泛型方法?
当使用EF6时,我试图在运行时动态切换表注释的模式值 到目前为止,我得到的是: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
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