我正在构建实体框架 (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
之间的差异=>localMigrations
databaseMigrations
localMigrations.Except(databaseMigrations);
所以我可以在那里传递我自己的一组 Id,这允许我创建一组自定义待定迁移。
但是还是有问题;DbMigrator
'sinternal override void Upgrade(IEnumerable<string> pendingMigrations, string targetMigrationId, stringlastMigrationId)
使用MigrationAssembly
EF 中定义的类的实例。
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
该类创建自定义迁移架构