我正在构建实体框架 (5) 的模块化实现,并且正在尝试实现模块化迁移。
这个想法是每个模块都可以注册其作为 DbMigration 实例的迁移(EF 已经使用它来注册迁移)。
我打算使用这个概念来迁移Application_Start数据库Modules_Loaded
Database.SetInitializer<YourContext>(
new MigrateDatabaseToLatestVersion<YourContext, YourMigrationsConfig>());
Database.Initialize(false);
有没有办法可以将模块注册的所有 DbMigrations 传递给MigrateDatabaseToLatestVersion?
研究
我最初以为我必须将 MigrateDatabaseToLatestVersion 子类化,但是在查看源代码后,我看不到可扩展性的一点,但它所做的只是
_config = new TMigrationsConfiguration
{
TargetDatabase = new DbConnectionInfo(connectionStringName)
};
接着
var migrator = new DbMigrator(_config);
migrator.Update();
所以我查看了 DbMigrator 的源代码,其中有一个方法我可以覆盖调用GetPendingMigrations它返回_historyRepository.GetPendingMigrations(_migrationAssembly.MigrationIds)
然后我看了一下课堂上的public virtual IEnumerable<string> GetPendingMigrations(IEnumerable<string> localMigrations)方法HistoryRepository,它的工作是找出已经发生了哪些迁移( )并返回和databaseMigrations之间的差异=>localMigrationsdatabaseMigrationslocalMigrations.Except(databaseMigrations);
所以我可以在那里传递我自己的一组 Id,这允许我创建一组自定义待定迁移。
但是还是有问题;DbMigrator'sinternal override void Upgrade(IEnumerable<string> pendingMigrations, string targetMigrationId, stringlastMigrationId)使用MigrationAssemblyEF 中定义的类的实例。
foreach (var pendingMigration in pendingMigrations)
{
var migration = _migrationAssembly.GetMigration(pendingMigration);
这是GetMigration(string migrationId):
public virtual DbMigration GetMigration(string migrationId)
{
DebugCheck.NotEmpty(migrationId);
var migration
= (DbMigration)_migrations
.SingleOrDefault(m => string.Equals(m.Id, migrationId, StringComparison.Ordinal));
if (migration != null)
{
migration.Reset();
}
return migration;
}
太完美了,我应该重写那个类......哦等等:
internal class MigrationAssembly
也是内部的。那么我怎么能覆盖这些属性呢?
这是指向源http://entityframework.codeplex.com的链接
更新
我无法在不编辑源代码的情况下找到一种方法。现在我正在寻找使用DbModelBuilder该类创建自定义迁移架构