sólo puede por ordenar obtener nombre enlazado enlazadas encabezado datos control columnas columna cambiar boton agregar c# visual-studio entity-framework entity-framework-5 ef-migrations

puede - ordenar gridview por columna c#



Migración EF para cambiar el tipo de datos de las columnas (5)

Este es un ejemplo para cambiar una columna existente a ''no nulo'' que ya tiene una restricción de clave externa. El nombre de la columna es "FKColumnName" en la tabla "SubTable" y hace referencia a la columna "Id" en la tabla "MainTable".

Up script:

Después de que la columna se convierte en "no admite nulos", el índice y la clave externa primero se descartan y luego se vuelven a crear.

Secuencia de comandos hacia abajo:

Aquí los pasos son idénticos, excepto que la columna se vuelve nulable nuevamente.

public partial class NameOfMigration : DbMigration { public override void Up() { DropForeignKey("dbo.SubTable", "FKColumnName", "dbo.MainTable"); DropIndex("dbo.SubTable", new[] { "FKColumnName" }); AlterColumn("dbo.SubTable", "FKColumnName", c => c.Int(nullable: false)); CreateIndex("dbo.SubTable", "FKColumnName"); AddForeignKey("dbo.SubTable", "FKColumnName", "dbo.MainTable", "Id"); } public override void Down() { DropForeignKey("dbo.SubTable", "FKColumnName", "dbo.MainTable"); DropIndex("dbo.SubTable", new[] { "FKColumnName" }); AlterColumn("dbo.SubTable", "FKColumnName", c => c.Int(nullable: true)); CreateIndex("dbo.SubTable", "FKColumnName"); AddForeignKey("dbo.SubTable", "FKColumnName", "dbo.MainTable", "Id"); } }

Tengo un modelo en mi proyecto de la siguiente manera:

public class Model { public int Id { get; set; } public long FromNo { get; set; } public long ToNo { get; set; } public string Content { get; set; } public long TicketNo { get; set; } }

La migración es la siguiente

public override void Down() { AlterColumn("dbo.Received", "FromNo", c => c.Long(nullable: false)); AlterColumn("dbo.Received", "ToNo", c => c.Long(nullable: false)); AlterColumn("dbo.Received", "TicketNo", c => c.Long(nullable: false)); } public override void Up() { AlterColumn("dbo.Received", "FromNo", c => c.String()); AlterColumn("dbo.Received", "ToNo", c => c.String()); AlterColumn("dbo.Received", "TicketNo", c => c.String()); }

cuando uso Update-Database, aparece el siguiente error:

El objeto ''DF__Receiv__FromN__25869641'' depende de la columna ''FromNo''. ALTER TABLE ALTER COLUMN FromNo failed porque uno o más objetos acceden a esta columna.

Estas tablas no tienen una clave externa o qué más, ¿cuál es el problema?


La mejor manera es resolver el problema para siempre.

Puede implementar una clase de generador SQL personalizada derivada de SqlServerMigrationSqlGenerator del espacio de nombres System.Data.Entity.SqlServer:

using System.Data.Entity.Migrations.Model; using System.Data.Entity.SqlServer; namespace System.Data.Entity.Migrations.Sql{ internal class FixedSqlServerMigrationSqlGenerator : SqlServerMigrationSqlGenerator { protected override void Generate(AlterColumnOperation alterColumnOperation){ ColumnModel column = alterColumnOperation.Column; var sql = String.Format(@"DECLARE @ConstraintName varchar(1000); DECLARE @sql varchar(1000); SELECT @ConstraintName = name FROM sys.default_constraints WHERE parent_object_id = object_id(''{0}'') AND col_name(parent_object_id, parent_column_id) = ''{1}''; IF(@ConstraintName is NOT Null) BEGIN set @sql=''ALTER TABLE {0} DROP CONSTRAINT ['' + @ConstraintName+ '']''; exec(@sql); END", alterColumnOperation.Table, column.Name); this.Statement(sql); base.Generate(alterColumnOperation); return; } protected override void Generate(DropColumnOperation dropColumnOperation){ var sql = String.Format(@"DECLARE @SQL varchar(1000) SET @SQL=''ALTER TABLE {0} DROP CONSTRAINT ['' + (SELECT name FROM sys.default_constraints WHERE parent_object_id = object_id(''{0}'') AND col_name(parent_object_id, parent_column_id) = ''{1}'') + '']''; PRINT @SQL; EXEC(@SQL); ", dropColumnOperation.Table, dropColumnOperation.Name); this.Statement(sql); base.Generate(dropColumnOperation); } } }

y establecer esta configuración:

internal sealed class Configuration : DbMigrationsConfiguration<MyDbContext> { public Configuration() { AutomaticMigrationsEnabled = true; SetSqlGenerator("System.Data.SqlClient", new FixedSqlServerMigrationSqlGenerator ()); } ... }


Si usas EF:

  • Eliminar la carpeta de migración y la base de datos
  • enable-migrations
  • add-migration initial
  • update-database

Aunque, esta solución eliminaría todos los elementos actuales en la base de datos. Si esta no es su intención, sugeriría una de las otras respuestas.


Usted tiene una restricción predeterminada en su columna. Primero debe eliminar la restricción y luego modificar su columna.

public override void Up() { Sql("ALTER TABLE dbo.Received DROP CONSTRAINT DF_Receiv_FromN__25869641"); AlterColumn("dbo.Received", "FromNo", c => c.String()); AlterColumn("dbo.Received", "ToNo", c => c.String()); AlterColumn("dbo.Received", "TicketNo", c => c.String()); }

Probablemente también deba eliminar las restricciones predeterminadas en sus otras columnas.

Acabo de ver el comentario de Andrey (lo sé, muy tarde) y él está en lo cierto. Entonces, un enfoque más sólido sería usar algo como:

DECLARE @con nvarchar(128) SELECT @con = name FROM sys.default_constraints WHERE parent_object_id = object_id(''dbo.Received'') AND col_name(parent_object_id, parent_column_id) = ''FromNo''; IF @con IS NOT NULL EXECUTE(''ALTER TABLE [dbo].[Received] DROP CONSTRAINT '' + @con)

Sé que esto probablemente no ayuda al OP, pero espero que ayude a cualquier otra persona que se encuentre con este problema.


static internal class MigrationExtensions { public static void DeleteDefaultContraint(this IDbMigration migration, string tableName, string colName, bool suppressTransaction = false) { var sql = new SqlOperation(String.Format(@"DECLARE @SQL varchar(1000) SET @SQL=''ALTER TABLE {0} DROP CONSTRAINT [''+(SELECT name FROM sys.default_constraints WHERE parent_object_id = object_id(''{0}'') AND col_name(parent_object_id, parent_column_id) = ''{1}'')+'']''; PRINT @SQL; EXEC(@SQL);", tableName, colName)) { SuppressTransaction = suppressTransaction }; migration.AddOperation(sql); } } public override void Up() { this.DeleteDefaultContraint("dbo.Received", "FromNo"); AlterColumn("dbo.Received", "FromNo", c => c.String()); this.DeleteDefaultContraint("dbo.Received", "ToNo"); AlterColumn("dbo.Received", "ToNo", c => c.String()); this.DeleteDefaultContraint("dbo.Received", "TicketNo"); AlterColumn("dbo.Received", "TicketNo", c => c.String()); }