protected virtual void Process(DropColumnOperation dropColumnOperation, Context context) { Check.NotNull(dropColumnOperation, "dropColumnOperation"); Check.NotNull(context, "context"); var entityType = context.SourceModel.EntityTypes.Single( t => NameBuilder.SchemaQualifiedTableName(t) == dropColumnOperation.TableName); var property = entityType.Properties.Single( p => NameBuilder.ColumnName(p) == dropColumnOperation.ColumnName); var extensions = property.SqlServer(); if (extensions.DefaultValue != null || extensions.DefaultExpression != null) { context.Operations.Add(OperationFactory.DropDefaultConstraintOperation(property)); } }
public virtual void GenerateColumnType( SchemaQualifiedName tableName, [NotNull] Column column, [NotNull] SqlBatchBuilder batchBuilder) { Check.NotNull(column, "column"); Check.NotNull(batchBuilder, "batchBuilder"); if (!string.IsNullOrEmpty(column.DataType)) { batchBuilder.Append(column.DataType); return; } var entityType = TargetModel.EntityTypes.Single(t => NameBuilder.SchemaQualifiedTableName(t) == tableName); var property = entityType.Properties.Single(p => NameBuilder.ColumnName(p) == column.Name); var isKey = property.IsKey() || property.IsForeignKey(); batchBuilder.Append(_typeMapper.GetTypeMapping(column.DataType, column.Name, column.ClrType, isKey, column.IsTimestamp).StoreTypeName); }
protected virtual void GetDataTypes( [NotNull] IEntityType entityType, [NotNull] IProperty property, [NotNull] Column newColumn, [NotNull] Context context, out string dataType, out string newDataType) { Check.NotNull(entityType, "entityType"); Check.NotNull(property, "property"); Check.NotNull(newColumn, "newColumn"); Check.NotNull(context, "context"); var isKey = property.IsKey() || property.IsForeignKey(); var extensions = property.SqlServer(); dataType = TypeMapper.GetTypeMapping( extensions.ColumnType, NameBuilder.ColumnName(property), property.PropertyType, isKey, property.IsConcurrencyToken) .StoreTypeName; newDataType = TypeMapper.GetTypeMapping( newColumn.DataType, newColumn.Name, newColumn.ClrType, isKey, newColumn.IsTimestamp) .StoreTypeName; }
protected override void GenerateComputedColumn(SchemaQualifiedName tableName, Column column, SqlBatchBuilder batchBuilder) { Check.NotNull(column, "column"); Check.NotNull(batchBuilder, "batchBuilder"); batchBuilder .Append(DelimitIdentifier(column.Name)) .Append(" AS ") .Append(column.DefaultSql); var entityType = TargetModel.EntityTypes.Single(t => NameBuilder.SchemaQualifiedTableName(t) == tableName); var property = entityType.Properties.Single(p => NameBuilder.ColumnName(p) == column.Name); if (!property.IsNullable || property.IsForeignKey()) { // TODO: Consider adding support for PERSISTED to SqlServer metadata extensions. batchBuilder.Append(" PERSISTED"); } GenerateNullConstraint(tableName, column, batchBuilder); }
protected virtual void Process(AlterColumnOperation alterColumnOperation, Context context) { Check.NotNull(alterColumnOperation, "alterColumnOperation"); Check.NotNull(context, "context"); var entityType = context.SourceModel.EntityTypes.Single( t => NameBuilder.SchemaQualifiedTableName(t) == alterColumnOperation.TableName); var property = entityType.Properties.Single( p => NameBuilder.ColumnName(p) == alterColumnOperation.NewColumn.Name); var extensions = property.SqlServer(); var newColumn = alterColumnOperation.NewColumn; string dataType, newDataType; GetDataTypes(entityType, property, newColumn, context, out dataType, out newDataType); var primaryKey = entityType.TryGetPrimaryKey(); if (primaryKey != null && primaryKey.Properties.Any(p => ReferenceEquals(p, property))) { if (context.Operations.Add(OperationFactory.DropPrimaryKeyOperation(primaryKey), (x, y) => x.TableName == y.TableName && x.PrimaryKeyName == y.PrimaryKeyName)) { context.Operations.Add(OperationFactory.AddPrimaryKeyOperation(primaryKey)); } } // TODO: Changing the length of a variable-length column used in a UNIQUE constraint is allowed. foreach (var uniqueConstraint in entityType.Keys.Where(k => k != primaryKey) .Where(uc => uc.Properties.Any(p => ReferenceEquals(p, property)))) { if (context.Operations.Add(OperationFactory.DropUniqueConstraintOperation(uniqueConstraint), (x, y) => x.TableName == y.TableName && x.UniqueConstraintName == y.UniqueConstraintName)) { context.Operations.Add(OperationFactory.AddUniqueConstraintOperation(uniqueConstraint)); } } foreach (var foreignKey in entityType.ForeignKeys .Where(fk => fk.Properties.Any(p => ReferenceEquals(p, property))) .Concat(context.SourceModel.EntityTypes .SelectMany(t => t.ForeignKeys) .Where(fk => fk.ReferencedProperties.Any(p => ReferenceEquals(p, property))))) { if (context.Operations.Add(OperationFactory.DropForeignKeyOperation(foreignKey), (x, y) => x.TableName == y.TableName && x.ForeignKeyName == y.ForeignKeyName)) { context.Operations.Add(OperationFactory.AddForeignKeyOperation(foreignKey)); } } if (dataType != newDataType || ((string.Equals(dataType, "varchar", StringComparison.OrdinalIgnoreCase) || string.Equals(dataType, "nvarchar", StringComparison.OrdinalIgnoreCase) || string.Equals(dataType, "varbinary", StringComparison.OrdinalIgnoreCase)) && newColumn.MaxLength > property.MaxLength)) { foreach (var index in entityType.Indexes .Where(ix => ix.Properties.Any(p => ReferenceEquals(p, property)))) { if (context.Operations.Add(OperationFactory.DropIndexOperation(index), (x, y) => x.TableName == y.TableName && x.IndexName == y.IndexName)) { context.Operations.Add(OperationFactory.CreateIndexOperation(index)); } } } if (!property.IsStoreComputed && (extensions.DefaultValue != null || extensions.DefaultExpression != null)) { context.Operations.Add(OperationFactory.DropDefaultConstraintOperation(property)); } if (property.IsConcurrencyToken || property.IsStoreComputed != alterColumnOperation.NewColumn.IsComputed) { context.Operations.Remove(alterColumnOperation); context.Operations.Add(OperationFactory.DropColumnOperation(property)); context.Operations.Add(new AddColumnOperation( alterColumnOperation.TableName, alterColumnOperation.NewColumn)); } }