实体框架迁移:防止删除列或表

时间:2015-06-13 16:53:22

标签: entity-framework ef-code-first ef-migrations

如果EF migration决定重命名column(或table),则会通过删除(旧)列然后添加具有新名称的列来实现此目的。这显然会导致数据丢失。

有没有办法阻止EF migration删除列并强制它使用RenameColumn

1 个答案:

答案 0 :(得分:1)

好吧,我没有找到明确而直截了当的解决方案。

我的解决方案隐藏 DbMigration类,其中使用基于代码的迁移生成的每个迁移都来自。我这样做是通过引入一个具有相同名称(DbMigration)的新类。然后我把它放在代码文件所在的同一个程序集和相同的命名空间中。这样,任何代码文件对原始DbMigration的引用都会转为假DbMigration。然后,我可以阻止删除列或仅通过显式请求允许它:

namespace MyProject.DAL.Migrations
{

    /// <summary>
    /// Customized DbMigration which protect 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.");
        }
    }
}

在代码文件中:

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");
        }
    }