private MigrationExecutionInfo GetPendingMigration()
{
ValidateConfiguredAssemblies();
var hasDeployedAssembly = (this.DeployedAssembly != null);
var deployedMigrationInfo = hasDeployedAssembly
? GetMigrationInfo(MigrationsSource.Deployed)
: null;
var targetMigrationInfo = GetMigrationInfo(MigrationsSource.Target);
if (targetMigrationInfo.Source == MigrationsSource.Target
&& targetMigrationInfo.GenericMigrator == null
&& hasDeployedAssembly)
{
//The target assembly does not contain a matching migrator / migration config
//This means we are rolling back past to a time before this context existed
//So we should use the deployed assembly migration with a target of "0"
var isDeployedAssemblyHasConfiguration =
deployedMigrationInfo.GenericMigrator.Configuration.GetType().FullName ==
targetMigrationInfo.ConfigurationType;
if (!isDeployedAssemblyHasConfiguration)
{
throw new InvalidOperationException("Deployed migration missing required migration configuration");
}
return new MigrationExecutionInfo
{
Migration = deployedMigrationInfo,
TargetMigrationId = "0" //Before initial create
};
}
else
{
var isDeployedAssemblyHasConfiguration = (deployedMigrationInfo != null) &&
(deployedMigrationInfo.GenericMigrator.Configuration.GetType().FullName ==
targetMigrationInfo.GenericMigrator.Configuration.GetType().FullName)
&&
(deployedMigrationInfo.GenericMigrator.Configuration.ContextType.FullName ==
targetMigrationInfo.GenericMigrator.Configuration.ContextType.FullName);
if (!isDeployedAssemblyHasConfiguration)
{
// there is no matching deployed migration, so just use the target
return new MigrationExecutionInfo {Migration = targetMigrationInfo};
}
if (targetMigrationInfo.GenericMigrator != null)
{
string targetMigrationId = targetMigrationInfo.GenericMigrator
.GetLocalMigrations()
.OrderBy(i => i)
.LastOrDefault();
if (string.IsNullOrEmpty(targetMigrationId))
{
return null;
}
string lastDeployedMigrationId = deployedMigrationInfo.GenericMigrator
.GetLocalMigrations()
.OrderBy(i => i)
.LastOrDefault();
Log.Debug(
"Last migration deployed is {lastDeployedMigrationId}. Latest target migration is {targetMigrationId}.",
lastDeployedMigrationId,
targetMigrationId);
var migrationComparisonResult = targetMigrationId.CompareTo(lastDeployedMigrationId);
if (migrationComparisonResult == 0)
{
// target migration is equal to the latest deployed migration
// so there is no migration to execute
return null;
}
var isUpwardMigration = (migrationComparisonResult > 0);
return new MigrationExecutionInfo
{
TargetMigrationId = targetMigrationId,
Migration = isUpwardMigration
? targetMigrationInfo
: deployedMigrationInfo
};
}
return null;
}
}