我正在尝试在使用EF6时动态切换我的表注释的架构值@ Runtime。
所以这就是我到目前为止所得到的:
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" });
}
}
我想要完成的是这样的事情(不起作用):
builder.Entity<dbSetType>().ToTable((tableAttribute as TableAttribute).Name, "NEW_SCHEMA_VALUE");
基本上,对于T我想拉取DbSets,确定实体中使用的类&lt;&gt; generic,获取TableAttribute,并将Schema设置为新值。
目前,在entityTypeConfigMethodInfo.Invoke上,我收到的错误是“无法对ContainsGenericParameters为true的类型或方法执行后期绑定操作”。
我错过了什么?
答案 0 :(得分:3)
嗯,是的,你期待什么?
你说你在这一行得到错误:
entityTypeConfigMethodInfo.Invoke(genericDbModelMethodInfo, new Object[] { (tableAttribute as TableAttribute).Name, "NEW_SCHEMA_VALUE" });
问题不在于这一行,而在于这一行:
MethodInfo entityTypeConfigMethodInfo = typeof(EntityTypeConfiguration<>).GetMethod("ToTable", new[] { typeof(String), typeof(String) });
你得到的方法ToTable
类型?
包含该方法的类型仍然是开放的泛型类型。您必须指定类型参数以使其成为特定类型,然后您可以获取要调用的方法。
换句话说,你需要这个:
MethodInfo entityTypeConfigMethodInfo =
typeof(EntityTypeConfiguration<>).MakeGenericType(...).GetMethod("ToTable", new[] { typeof(String), typeof(String) });
^-------------------^
答案 1 :(得分:1)
要为第二次调用获取正确的封闭泛型methodinfo,请将代码重写为:
MethodInfo genericDbModelMethodInfo = dbModelMethodInfo.MakeGenericMethod(dbSetType);
MethodInfo entityTypeConfigMethodInfo = genericDbModelMethodInfo.ReturnType.GetMethod("ToTable", new[] { typeof(String), typeof(String) });
然后你必须使用genericDbModelMethodInfo.Invoke
调用的返回值作为第二个调用中的第一个参数。
var obj = genericDbModelMethodInfo.Invoke(builder, null);
entityTypeConfigMethodInfo.Invoke(obj, new Object[] { (tableAttribute as TableAttribute).Name, "NEW_SCHEMA_VALUE" });
这是因为MethodInfo.Invoke
中的第一个参数是您要调用该方法的对象。
答案 2 :(得分:0)
由于EntityTypeConfiguration是通用类型,您是否可以指定对象中用于 EntityTypeConfiguration 的Generic参数的类型。 例如:
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;
}
}