Entity Framework Migrations: Prevent dropping column or table

1.2k Views Asked by At

If EF migration decides to rename a column (or a table), it fulfills this by dropping the (old) column and then adding a column with the new name. This clearly leads to data loss.

Is there any way to prevent EF migration from dropping a column and force it to use RenameColumn instead?

1

There are 1 best solutions below

0
On

Well, I didn't find a clear and straightforward solution.

My solution is hiding DbMigration class which every migration that was generated using code-based migration is derived from. I do this by introducing a new class with the same name (DbMigration). Then I put it inside the same assembly and same namespace where code files reside. This way, any reference of code files to the original DbMigration resolves to the new DbMigration type. Then, I can switch dropping a column ON or Off:

namespace MyProject.DAL.Migrations
{
   
    /// <summary>
    /// Customized DbMigration which protects columns to be dropped accidentally
    /// </summary>
    public abstract class DbMigration : global::System.Data.Entity.Migrations.DbMigration
    {
        public bool AlloDropColumn { get; set; }
        protected internal new void DropColumn(string table, string name, object anonymousArguments = null)
        {
            if (!AlloDropColumn)
                throw new Exception("MyProject: Dropping a column while updating database is prohibited. If you really want to drop column(s), set property 'AllowDropColumn' true.");
        }
    }
}

And in a code file:

public partial class _1 : DbMigration
    {
        public override void Up()
        {
            AlloDropColumn = true; // To allow column drop
            AddColumn("driver.TruckDriver", "FullName2", c => c.String());
            DropColumn("driver.TruckDriver", "FullName");
        }
        
        public override void Down()
        {
            AddColumn("driver.TruckDriver", "FullName", c => c.String());
            DropColumn("driver.TruckDriver", "FullName2");
        }
    }