使用运行时类型的泛型类型的方法
问题描述:
我想在运行时使用实体框架迁移数据库。
这就是你通常会这么做:使用运行时类型的泛型类型的方法
Database.SetInitializer<TContext>(new MigrateDatabaseToLatestVersion<TContext,TMigrationsConfiguration>);
}
但是我不知道TContext或TMigrationsConfiguration到运行时。
我该如何使用运行时类型执行此方法?
更新1个
@Alexander Balte的建议让我在使用IDatabaseInitializer
所以这个编译没有错误的接口:
foreach (IDatabaseInitializer<DbContext> initializer in moduleNeedingMigration.initializers)
{
System.Data.Entity.Database.SetInitializer(initializer);
}
但是我无法做到这一点:
public IEnumerable<IDatabaseInitializer<DbContext>> initializers
{
get
{
List<IDatabaseInitializer<Module1Context>> list = new List<IDatabaseInitializer<Module1Context>>();
MigrateDatabaseToLatestVersion<Module1Context, Configuration> init = new MigrateDatabaseToLatestVersion<Module1Context, Configuration>();
list.Add(init);
return list;//Error cannot convert type List<IDatabaseInitializer<Module1Context>> to IEnumerable<IDatabaseInitializer<DbContext>>
}
}
注意是Module1Context继承的DbContext
更新2
这编译:
return list.Cast<IDatabaseInitializer<UpfContext>>();
然而,当我运行的应用程序,我得到这个错误:
System.Data.Entity.MigrateDatabaseToLatestVersion`2[Module1.Models.Module1Context,Module1.Migrations.Configuration]' to type 'System.Data.Entity.IDatabaseInitializer`1[System.Data.Entity.DbContext]'.
答
如果你知道TContext
或TMigrationsConfiguration
所有可能的集合可以创建somethig像工厂方法将由具体类型的TContext
和TMigrationsConfiguration
回到你MigrateDatabaseToLatestVersion
。
喜欢的东西:
private static Dictionary<Tuple<Type, Type>, Func<object>> _map = new Dictionary<Tuple<Type, Type>, Func<object>>();
public static MigrateDatabaseToLatestVersion<TContext, TMigrationsConfiguration> CreateMigrateDatabaseToLatestVersion<TContext, TMigrationsConfiguration>(TContext type, TMigrationsConfiguration configuration)
{
Type contextType = typeof (TContext);
Type configurationType = typeof(TMigrationsConfiguration);
Func<object> builder;
if (!_map.TryGetValue(new Tuple<Type, Type>(contextType, configurationType), out builder))
throw new KeyNotFoundException();
return (MigrateDatabaseToLatestVersion<TContext, TMigrationsConfiguration>)builder();
}
字典_map
应与所有可能的集合的泛型类型的参数进行初始化。像:
_map[new Tuple<Type, Type>(typeof(MyDbContext), typeof(MyDbMigrationsConfiguration)) =() => new MigrateDatabaseToLatestVersion<MyDbContext, MyDbMigrationsConfiguration>();
你有一个像'型T'一个变量,或者它是一个通用类'类胡说'里面? –
我在运行时有一个变量 – MrJD
因为'IDatabaseInitializer'是逆变的,所以不可能将'IDatabaseInitializer'强制转换为'IDatabaseInitializer '。 –