protected virtual IEnumerable <MigrationOperation> Add([NotNull] IProperty target, bool inline = false) { var targetAnnotations = Annotations.For(target); var targetEntityTypeAnnotations = Annotations.For(target.DeclaringEntityType.RootType()); var operation = new AddColumnOperation { Schema = targetEntityTypeAnnotations.Schema, Table = targetEntityTypeAnnotations.TableName, Name = targetAnnotations.ColumnName, ClrType = target.ClrType.UnwrapNullableType().UnwrapEnumType(), ColumnType = targetAnnotations.ColumnType, IsNullable = target.IsColumnNullable(), DefaultValue = targetAnnotations.DefaultValue ?? (inline || target.IsColumnNullable() ? null : GetDefaultValue(target.ClrType)), DefaultValueSql = target.ValueGenerated == ValueGenerated.OnAdd ? targetAnnotations.GeneratedValueSql : null, ComputedColumnSql = target.ValueGenerated == ValueGenerated.OnAddOrUpdate ? targetAnnotations.GeneratedValueSql : null }; CopyAnnotations(MigrationsAnnotations.For(target), operation); yield return(operation); }
protected virtual void CreateIndexes( [CanBeNull] IProperty property, [NotNull] MigrationCommandListBuilder builder) { Check.NotNull(builder, nameof(builder)); if (property == null) { return; } foreach (var index in property.GetContainingIndexes()) { var operation = new CreateIndexOperation { IsUnique = index.IsUnique, Name = Annotations.For(index).Name, Schema = Annotations.For(index.DeclaringEntityType).Schema, Table = Annotations.For(index.DeclaringEntityType).TableName, Columns = index.Properties.Select(p => Annotations.For(p).ColumnName).ToArray() }; operation.AddAnnotations(_migrationsAnnotations.For(index)); Generate(operation, index.DeclaringEntityType.Model, builder, terminate: false); builder.AppendLine(SqlGenerationHelper.StatementTerminator); } }
protected virtual IEnumerable <MigrationOperation> Add(IForeignKey target, DiffContext diffContext) { var declaringRootEntityType = target.DeclaringEntityType.RootType(); var targetEntityTypeAnnotations = Annotations.For(declaringRootEntityType); var targetPrincipalEntityTypeAnnotations = Annotations.For(target.PrincipalEntityType.RootType()); // TODO: Set OnDelete (See #1084) var operation = new AddForeignKeyOperation { Schema = targetEntityTypeAnnotations.Schema, Table = targetEntityTypeAnnotations.TableName, Name = Annotations.For(target).Name, Columns = GetColumns(target.Properties), PrincipalSchema = targetPrincipalEntityTypeAnnotations.Schema, PrincipalTable = targetPrincipalEntityTypeAnnotations.TableName, PrincipalColumns = GetColumns(target.PrincipalKey.Properties) }; CopyAnnotations(MigrationsAnnotations.For(target), operation); var createTableOperation = diffContext.FindCreate(declaringRootEntityType); if (createTableOperation != null) { createTableOperation.ForeignKeys.Add(operation); } else { yield return(operation); } }
protected virtual IEnumerable <MigrationOperation> Add([NotNull] IForeignKey target, [NotNull] DiffContext diffContext) { var declaringRootEntityType = target.DeclaringEntityType.RootType(); var targetEntityTypeAnnotations = Annotations.For(declaringRootEntityType); var targetPrincipalEntityTypeAnnotations = Annotations.For(target.PrincipalEntityType.RootType()); var operation = new AddForeignKeyOperation { Schema = targetEntityTypeAnnotations.Schema, Table = targetEntityTypeAnnotations.TableName, Name = Annotations.For(target).Name, Columns = GetColumns(target.Properties), PrincipalSchema = targetPrincipalEntityTypeAnnotations.Schema, PrincipalTable = targetPrincipalEntityTypeAnnotations.TableName, PrincipalColumns = GetColumns(target.PrincipalKey.Properties), OnDelete = target.DeleteBehavior == DeleteBehavior.Cascade ? ReferentialAction.Cascade : target.DeleteBehavior == DeleteBehavior.SetNull ? ReferentialAction.SetNull : ReferentialAction.Restrict }; CopyAnnotations(MigrationsAnnotations.For(target), operation); var createTableOperation = diffContext.FindCreate(declaringRootEntityType); if (createTableOperation != null) { createTableOperation.ForeignKeys.Add(operation); } else { yield return(operation); } }
protected virtual IEnumerable <MigrationOperation> Add([NotNull] IKey target) { var targetAnnotations = Annotations.For(target); var targetEntityTypeAnnotations = Annotations.For(target.DeclaringEntityType.RootType()); MigrationOperation operation; if (target.IsPrimaryKey()) { operation = new AddPrimaryKeyOperation { Schema = targetEntityTypeAnnotations.Schema, Table = targetEntityTypeAnnotations.TableName, Name = targetAnnotations.Name, Columns = GetColumns(target.Properties) }; } else { operation = new AddUniqueConstraintOperation { Schema = targetEntityTypeAnnotations.Schema, Table = targetEntityTypeAnnotations.TableName, Name = targetAnnotations.Name, Columns = GetColumns(target.Properties) }; } CopyAnnotations(MigrationsAnnotations.For(target), operation); yield return(operation); }
protected virtual IEnumerable <MigrationOperation> Diff( [NotNull] IEntityType source, [NotNull] IEntityType target, [NotNull] DiffContext diffContext) { var sourceAnnotations = Annotations.For(source); var targetAnnotations = Annotations.For(target); var schemaChanged = sourceAnnotations.Schema != targetAnnotations.Schema; var renamed = sourceAnnotations.TableName != targetAnnotations.TableName; if (schemaChanged || renamed) { yield return(new RenameTableOperation { Schema = sourceAnnotations.Schema, Name = sourceAnnotations.TableName, NewSchema = schemaChanged ? targetAnnotations.Schema : null, NewName = renamed ? targetAnnotations.TableName : null }); } diffContext.AddMapping(source, target); var operations = Diff(GetPropertiesInHierarchy(source), GetPropertiesInHierarchy(target), diffContext) .Concat(Diff(source.GetKeys(), target.GetKeys(), diffContext)) .Concat(Diff(GetIndexesInHierarchy(source), GetIndexesInHierarchy(target), diffContext)); foreach (var operation in operations) { yield return(operation); } }
protected virtual IEnumerable <MigrationOperation> Add([NotNull] IEntityType target, [NotNull] DiffContext diffContext) { var targetAnnotations = Annotations.For(target); var createTableOperation = new CreateTableOperation { Schema = targetAnnotations.Schema, Name = targetAnnotations.TableName }; CopyAnnotations(MigrationsAnnotations.For(target), createTableOperation); createTableOperation.Columns.AddRange(GetPropertiesInHierarchy(target).SelectMany(p => Add(p, inline: true)).Cast <AddColumnOperation>()); var primaryKey = target.FindPrimaryKey(); createTableOperation.PrimaryKey = Add(primaryKey).Cast <AddPrimaryKeyOperation>().Single(); createTableOperation.UniqueConstraints.AddRange( target.GetKeys().Where(k => k != primaryKey).SelectMany(Add).Cast <AddUniqueConstraintOperation>()); diffContext.AddCreate(target, createTableOperation); yield return(createTableOperation); foreach (var operation in GetIndexesInHierarchy(target).SelectMany(Add)) { yield return(operation); } }
protected virtual IEnumerable <MigrationOperation> Diff([NotNull] IIndex source, [NotNull] IIndex target) { var sourceEntityTypeAnnotations = Annotations.For(source.DeclaringEntityType.RootType()); var sourceName = Annotations.For(source).Name; var targetName = Annotations.For(target).Name; if (sourceName != targetName) { yield return(new RenameIndexOperation { Schema = sourceEntityTypeAnnotations.Schema, Table = sourceEntityTypeAnnotations.TableName, Name = sourceName, NewName = targetName }); } if ((source.IsUnique != target.IsUnique) || HasDifferences(MigrationsAnnotations.For(source), MigrationsAnnotations.For(target))) { var operations = Remove(source).Concat(Add(target)); foreach (var operation in operations) { yield return(operation); } } }
protected virtual void DropIndexes( [CanBeNull] IProperty property, [NotNull] MigrationCommandListBuilder builder) { Check.NotNull(builder, nameof(builder)); if (property == null) { return; } foreach (var index in property.GetContainingIndexes()) { var operation = new DropIndexOperation { Schema = Annotations.For(index.DeclaringEntityType).Schema, Table = Annotations.For(index.DeclaringEntityType).TableName, Name = Annotations.For(index).Name }; operation.AddAnnotations(_migrationsAnnotations.ForRemove(index)); Generate(operation, index.DeclaringEntityType.Model, builder, terminate: false); builder.AppendLine(SqlGenerationHelper.StatementTerminator); } }
protected virtual IEnumerable <MigrationOperation> Diff([NotNull] IProperty source, [NotNull] IProperty target) { var sourceAnnotations = Annotations.For(source); var sourceEntityTypeAnnotations = Annotations.For(source.DeclaringEntityType.RootType()); var targetAnnotations = Annotations.For(target); if (sourceAnnotations.ColumnName != targetAnnotations.ColumnName) { yield return(new RenameColumnOperation { Schema = sourceEntityTypeAnnotations.Schema, Table = sourceEntityTypeAnnotations.TableName, Name = sourceAnnotations.ColumnName, NewName = targetAnnotations.ColumnName }); } var sourceColumnType = sourceAnnotations.ColumnType ?? TypeMapper.GetMapping(source).DefaultTypeName; var targetColumnType = targetAnnotations.ColumnType ?? TypeMapper.GetMapping(target).DefaultTypeName; var targetMigrationsAnnotations = MigrationsAnnotations.For(target); var isSourceColumnNullable = source.IsColumnNullable(); var isTargetColumnNullable = target.IsColumnNullable(); var isNullableChanged = isSourceColumnNullable != isTargetColumnNullable; var columnTypeChanged = sourceColumnType != targetColumnType; if (isNullableChanged || columnTypeChanged || sourceAnnotations.DefaultValueSql != targetAnnotations.DefaultValueSql || sourceAnnotations.ComputedValueSql != targetAnnotations.ComputedValueSql || !Equals(sourceAnnotations.DefaultValue, targetAnnotations.DefaultValue) || HasDifferences(MigrationsAnnotations.For(source), targetMigrationsAnnotations)) { var isDestructiveChange = (isNullableChanged && isSourceColumnNullable) // TODO: Detect type narrowing || columnTypeChanged; var alterColumnOperation = new AlterColumnOperation { Schema = sourceEntityTypeAnnotations.Schema, Table = sourceEntityTypeAnnotations.TableName, Name = sourceAnnotations.ColumnName, ClrType = target.ClrType.UnwrapNullableType().UnwrapEnumType(), ColumnType = targetAnnotations.ColumnType, IsNullable = isTargetColumnNullable, DefaultValue = targetAnnotations.DefaultValue, DefaultValueSql = targetAnnotations.DefaultValueSql, ComputedColumnSql = targetAnnotations.ComputedValueSql, IsDestructiveChange = isDestructiveChange }; CopyAnnotations(targetMigrationsAnnotations, alterColumnOperation); yield return(alterColumnOperation); } }
protected virtual IEnumerable <MigrationOperation> Diff( [NotNull] IEnumerable <IKey> source, [NotNull] IEnumerable <IKey> target, [NotNull] DiffContext diffContext) => DiffCollection( source, target, Diff, Add, Remove, (s, t) => (Annotations.For(s).Name == Annotations.For(t).Name) && s.Properties.Select(diffContext.FindTarget).SequenceEqual(t.Properties) && (s.IsPrimaryKey() == t.IsPrimaryKey()));
protected virtual IEnumerable <MigrationOperation> Remove([NotNull] IIndex source) { var sourceEntityTypeAnnotations = Annotations.For(source.DeclaringEntityType.RootType()); yield return(new DropIndexOperation { Name = Annotations.For(source).Name, Schema = sourceEntityTypeAnnotations.Schema, Table = sourceEntityTypeAnnotations.TableName }); }
protected virtual IEnumerable <MigrationOperation> Remove(IProperty source) { var sourceEntityTypeAnnotations = Annotations.For(source.DeclaringEntityType.RootType()); yield return(new DropColumnOperation { Schema = sourceEntityTypeAnnotations.Schema, Table = sourceEntityTypeAnnotations.TableName, Name = Annotations.For(source).ColumnName }); }
protected virtual IEnumerable <MigrationOperation> Diff( [NotNull] IEnumerable <IIndex> source, [NotNull] IEnumerable <IIndex> target, [NotNull] DiffContext diffContext) => DiffCollection( source, target, Diff, Add, Remove, (s, t) => string.Equals( Annotations.For(s).Name, Annotations.For(t).Name, StringComparison.OrdinalIgnoreCase) && s.Properties.Select(diffContext.FindTarget).SequenceEqual(t.Properties), (s, t) => s.Properties.Select(diffContext.FindTarget).SequenceEqual(t.Properties));
protected virtual IEnumerable <MigrationOperation> Remove(IEntityType source, DiffContext diffContext) { var sourceAnnotations = Annotations.For(source); var operation = new DropTableOperation { Schema = sourceAnnotations.Schema, Name = sourceAnnotations.TableName }; diffContext.AddDrop(source, operation); yield return(operation); }
protected virtual IEnumerable <MigrationOperation> Diff( [NotNull] IEnumerable <IForeignKey> source, [NotNull] IEnumerable <IForeignKey> target, [NotNull] DiffContext diffContext) => DiffCollection( source, target, (s, t) => Diff(s, t, diffContext), t => Add(t, diffContext), s => Remove(s, diffContext), (s, t) => (Annotations.For(s).Name == Annotations.For(t).Name) && s.Properties.Select(diffContext.FindTarget).SequenceEqual(t.Properties) && (diffContext.FindTarget(s.PrincipalEntityType.RootType()) == t.PrincipalEntityType.RootType()) && s.PrincipalKey.Properties.Select(diffContext.FindTarget).SequenceEqual(t.PrincipalKey.Properties) && (s.DeleteBehavior == t.DeleteBehavior));
protected virtual IEnumerable <MigrationOperation> Diff( IEnumerable <IForeignKey> source, IEnumerable <IForeignKey> target, DiffContext diffContext) => DiffCollection( source, target, (s, t) => Diff(s, t, diffContext), t => Add(t, diffContext), s => Remove(s, diffContext), (s, t) => { return(Annotations.For(s).Name == Annotations.For(t).Name && s.Properties.Select(diffContext.FindTarget).SequenceEqual(t.Properties) && diffContext.FindTarget(s.PrincipalEntityType.RootType()) == t.PrincipalEntityType.RootType() && s.PrincipalKey.Properties.Select(diffContext.FindTarget).SequenceEqual(t.PrincipalKey.Properties)); });
protected virtual IEnumerable <MigrationOperation> Add([NotNull] IIndex target) { var targetEntityTypeAnnotations = Annotations.For(target.DeclaringEntityType.RootType()); var operation = new CreateIndexOperation { Name = Annotations.For(target).Name, Schema = targetEntityTypeAnnotations.Schema, Table = targetEntityTypeAnnotations.TableName, Columns = GetColumns(target.Properties), IsUnique = target.IsUnique }; CopyAnnotations(MigrationsAnnotations.For(target), operation); yield return(operation); }
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 IEnumerable <MigrationOperation> Diff( [CanBeNull] IModel source, [CanBeNull] IModel target, [NotNull] DiffContext diffContext) => (source != null) && (target != null) ? Diff(GetSchemas(source), GetSchemas(target)) .Concat(Diff(source.GetRootEntityTypes(), target.GetRootEntityTypes(), diffContext)) .Concat( Diff(Annotations.For(source).Sequences, Annotations.For(target).Sequences)) .Concat( Diff( source.GetEntityTypes().SelectMany(t => t.GetDeclaredForeignKeys()), target.GetEntityTypes().SelectMany(t => t.GetDeclaredForeignKeys()), diffContext)) : target != null ? Add(target, diffContext) : source != null ? Remove(source, diffContext) : Enumerable.Empty <MigrationOperation>();
protected virtual IEnumerable <MigrationOperation> Diff( [NotNull] IEnumerable <IProperty> source, [NotNull] IEnumerable <IProperty> target, [NotNull] DiffContext diffContext) => DiffCollection( source, target, (s, t) => { diffContext.AddMapping(s, t); return(Diff(s, t)); }, t => Add(t), Remove, (s, t) => string.Equals(s.Name, t.Name, StringComparison.OrdinalIgnoreCase), (s, t) => string.Equals( Annotations.For(s).ColumnName, Annotations.For(t).ColumnName, StringComparison.OrdinalIgnoreCase));
protected virtual IEnumerable <MigrationOperation> Diff( [NotNull] IEnumerable <IEntityType> source, [NotNull] IEnumerable <IEntityType> target, [NotNull] DiffContext diffContext) => DiffCollection( source, target, (s, t) => Diff(s, t, diffContext), t => Add(t, diffContext), s => Remove(s, diffContext), (s, t) => string.Equals(s.Name, t.Name, StringComparison.OrdinalIgnoreCase), (s, t) => string.Equals( Annotations.For(s).Schema, Annotations.For(t).Schema, StringComparison.OrdinalIgnoreCase) && string.Equals( Annotations.For(s).TableName, Annotations.For(t).TableName, StringComparison.OrdinalIgnoreCase), (s, t) => string.Equals( Annotations.For(s).TableName, Annotations.For(t).TableName, StringComparison.OrdinalIgnoreCase));
protected virtual IEnumerable <MigrationOperation> Remove([NotNull] IKey source) { var sourceAnnotations = Annotations.For(source); var sourceEntityTypeAnnotations = Annotations.For(source.DeclaringEntityType.RootType()); if (source.IsPrimaryKey()) { yield return(new DropPrimaryKeyOperation { Schema = sourceEntityTypeAnnotations.Schema, Table = sourceEntityTypeAnnotations.TableName, Name = sourceAnnotations.Name }); } else { yield return(new DropUniqueConstraintOperation { Schema = sourceEntityTypeAnnotations.Schema, Table = sourceEntityTypeAnnotations.TableName, Name = sourceAnnotations.Name }); } }
protected virtual IEnumerable <string> GetSchemas([NotNull] IModel model) => model.GetRootEntityTypes().Select(t => Annotations.For(t).Schema).Where(s => !string.IsNullOrEmpty(s)) .Distinct();
protected virtual string[] GetColumns([NotNull] IEnumerable <IProperty> properties) => properties.Select(p => Annotations.For(p).ColumnName).ToArray();
protected virtual IEnumerable <MigrationOperation> Add([NotNull] IModel target, [NotNull] DiffContext diffContext) => GetSchemas(target).SelectMany(Add) .Concat(target.GetRootEntityTypes().SelectMany(t => Add(t, diffContext))) .Concat(Annotations.For(target).Sequences.SelectMany(Add)) .Concat(target.GetEntityTypes().SelectMany(t => t.GetDeclaredForeignKeys()).SelectMany(k => Add(k, diffContext)));
protected virtual IEnumerable <MigrationOperation> Remove([NotNull] IModel source, [NotNull] DiffContext diffContext) => source.GetRootEntityTypes().SelectMany(t => Remove(t, diffContext)) .Concat(Annotations.For(source).Sequences.SelectMany(Remove));
private IEnumerable <IIndex> GetIndexesInHierarchy(IEntityType entityType) => entityType.GetDeclaredIndexes().Concat(entityType.GetDerivedTypes().SelectMany(t => t.GetDeclaredIndexes())) .Distinct((x, y) => Annotations.For(x).Name == Annotations.For(y).Name);
private IEnumerable <IProperty> GetPropertiesInHierarchy(IEntityType entityType) => entityType.GetDeclaredProperties().Concat(entityType.GetDerivedTypes().SelectMany(t => t.GetDeclaredProperties())) .Distinct((x, y) => Annotations.For(x).ColumnName == Annotations.For(y).ColumnName);