protected virtual IEnumerable <MigrationOperation> Remove([NotNull] IForeignKey source, [NotNull] DiffContext diffContext) { var declaringRootEntityType = source.DeclaringEntityType.RootType(); var sourceEntityTypeAnnotations = Annotations.For(declaringRootEntityType); var dropTableOperation = diffContext.FindDrop(declaringRootEntityType); if (dropTableOperation == null) { yield return(new DropForeignKeyOperation { Schema = sourceEntityTypeAnnotations.Schema, Table = sourceEntityTypeAnnotations.TableName, Name = Annotations.For(source).Name }); } }
protected virtual IReadOnlyList <MigrationOperation> Sort( [NotNull] IEnumerable <MigrationOperation> operations, [NotNull] DiffContext diffContext) { Check.NotNull(operations, nameof(operations)); var dropForeignKeyOperations = new List <MigrationOperation>(); var dropOperations = new List <MigrationOperation>(); var dropColumnOperations = new List <MigrationOperation>(); var dropTableOperations = new List <DropTableOperation>(); var ensureSchemaOperations = new List <MigrationOperation>(); var createSequenceOperations = new List <MigrationOperation>(); var createTableOperations = new List <CreateTableOperation>(); var alterOperations = new List <MigrationOperation>(); var renameOperations = new List <MigrationOperation>(); var renameIndexOperations = new List <MigrationOperation>(); var renameTableOperations = new List <MigrationOperation>(); var leftovers = new List <MigrationOperation>(); foreach (var operation in operations) { var type = operation.GetType(); if (type == typeof(DropForeignKeyOperation)) { dropForeignKeyOperations.Add(operation); } else if (_dropOperationTypes.Contains(type)) { dropOperations.Add(operation); } else if (type == typeof(DropColumnOperation)) { dropColumnOperations.Add(operation); } else if (type == typeof(DropTableOperation)) { dropTableOperations.Add((DropTableOperation)operation); } else if (type == typeof(EnsureSchemaOperation)) { ensureSchemaOperations.Add(operation); } else if (type == typeof(CreateSequenceOperation)) { createSequenceOperations.Add(operation); } else if (type == typeof(CreateTableOperation)) { createTableOperations.Add((CreateTableOperation)operation); } else if (_alterOperationTypes.Contains(type)) { alterOperations.Add(operation); } else if (_renameOperationTypes.Contains(type)) { renameOperations.Add(operation); } else if (type == typeof(RenameIndexOperation)) { renameIndexOperations.Add(operation); } else if (type == typeof(RenameTableOperation)) { renameTableOperations.Add(operation); } else { Debug.Assert(false, "Unexpected operation type: " + operation.GetType()); leftovers.Add(operation); } } var createTableGraph = new Multigraph <CreateTableOperation, AddForeignKeyOperation>(); createTableGraph.AddVertices(createTableOperations); foreach (var createTableOperation in createTableOperations) { foreach (var addForeignKeyOperation in createTableOperation.ForeignKeys) { if ((addForeignKeyOperation.Table == addForeignKeyOperation.PrincipalTable) && (addForeignKeyOperation.Schema == addForeignKeyOperation.PrincipalSchema)) { continue; } var principalCreateTableOperation = createTableOperations.FirstOrDefault( o => (o.Name == addForeignKeyOperation.PrincipalTable) && (o.Schema == addForeignKeyOperation.PrincipalSchema)); if (principalCreateTableOperation != null) { createTableGraph.AddEdge(principalCreateTableOperation, createTableOperation, addForeignKeyOperation); } } } createTableOperations = createTableGraph.TopologicalSort( (principalCreateTableOperation, createTableOperation, addForeignKeyOperations) => { foreach (var addForeignKeyOperation in addForeignKeyOperations) { createTableOperation.ForeignKeys.Remove(addForeignKeyOperation); alterOperations.Add(addForeignKeyOperation); } return(true); }).ToList(); var dropTableGraph = new Multigraph <DropTableOperation, IForeignKey>(); dropTableGraph.AddVertices(dropTableOperations); foreach (var dropTableOperation in dropTableOperations) { var entityType = diffContext.GetMetadata(dropTableOperation); foreach (var foreignKey in GetForeignKeysInHierarchy(entityType)) { var principalRootEntityType = foreignKey.PrincipalEntityType.RootType(); if (entityType == principalRootEntityType) { continue; } var principalDropTableOperation = diffContext.FindDrop(principalRootEntityType); if (principalDropTableOperation != null) { dropTableGraph.AddEdge(dropTableOperation, principalDropTableOperation, foreignKey); } } } var newDiffContext = new DiffContext(); dropTableOperations = dropTableGraph.TopologicalSort( (dropTableOperation, principalDropTableOperation, foreignKeys) => { dropForeignKeyOperations.AddRange(foreignKeys.SelectMany(c => Remove(c, newDiffContext))); return(true); }).ToList(); return(dropForeignKeyOperations .Concat(dropOperations) .Concat(dropColumnOperations) .Concat(dropTableOperations) .Concat(ensureSchemaOperations) .Concat(createSequenceOperations) .Concat(createTableOperations) .Concat(alterOperations) .Concat(renameOperations) .Concat(renameIndexOperations) .Concat(renameTableOperations) .Concat(leftovers) .ToArray()); }