更新与实体框架code首先在MVC现有数据库 [英] Update existing database with Entity Framework Code First in MVC

查看:180
本文介绍了更新与实体框架code首先在MVC现有数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的MVC应用程序我用实体框架6和创造了code第一种方法的数据库。经过一定时间后,我通过添加新的列,并除去一些​​列更新实体类中的一个。为了反映这些数据库更改我也跟着下面的步骤:


  

      
  1. 删除项目的迁移文件夹中。

  2.   
  3. 删除的__MigrationHistory数据库表中。

  4.   
  5. 然后运行程序包管理器控制台执行以下命令:

      启用的迁移-EnableAutomaticMigrations -Force


  6.   
  7. 添加配置文件下面几行:

      AutomaticMigrationsEnabled = TRUE;

              AutomaticMigrationDataLossAllowed = TRUE;


  8.   
  9. 运行:

      添加迁移初始


  10.   
  11. 最后,运行:

      更新,数据库-Verbose

  12.   

不过,我遇到一个错误的已经有一个名为在数据库'XXX'的对象。

要摆脱这个问题,我发表意见code在第5步之后创建的初始文件向上的方法。这prevent错误,但没有在数据库中更改(更新实体表仍是一样的)。
哪里错了吗?在此先感谢您的帮助。

这里是向上的方法,我在migration.cs文件中评论道:

 公共覆盖无效向上()
    {
        CREATETABLE(
            dbo.City
            C =>新
                {
                    ID = c.Int(可空:假的,身份:真)
                    名称= c.String(可空:假),
                    RegionID = c.Int(可空:假),
                })
            .PrimaryKey(T => t.ID)
            .ForeignKey(dbo.Region,T => t.RegionID)
            的.index(T => t.RegionID);        CREATETABLE(
            dbo.Multiplier
            C =>新
                {
                    ID = c.Int(可空:假的,身份:真)
                    状态= c.Int(可空:假),
                    期限= c.Int(可空:假),
                    CityID = c.Int(可空:假),
                    WhoIsOnline = c.String(可空:假),
                    用户ID = c.String(可空:假),
                    InstituteName = c.String(可空:假),
                    InstituteStatusID = c.Int(可空:假),
                    InstituteAccreditationDate = c.DateTime(可空:假),
                    地址= c.String(可空:假),
                    手机= c.String(可空:假),
                    传真= c.String(),
                    电子邮件= c.String(可空:假),
                    EurodeskEmail = c.String(可空:假),
                    网页= c.String()
                    联系人姓名= c.String(可空:假),
                    ContactSurname = c.String(可空:假),
                    ContactJobTitle = c.String(),
                    ContactAssignmentDate = c.DateTime(),
                    ContactWorkingStart = c.String(),
                    ContactWorkingkEnd = c.String(),
                    ContactPhone = c.String(),
                    ContactMobile = c.String(可空:假),
                    ContactEmail = c.String(可空:假),
                    ContactCityID = c.Int(可空:假),
                    LegalRe presentativeName = c.String(可空:假),
                    LegalRe presentativeSurname = c.String(可空:假),
                })
            .PrimaryKey(T => t.ID)
            .ForeignKey(dbo.City,T => t.CityID)
            .ForeignKey(dbo.InstituteStatus,T => t.InstituteStatusID)
            的.index(T => t.CityID)
            的.index(T => t.InstituteStatusID);        CREATETABLE(
            dbo.InstituteStatus
            C =>新
                {
                    ID = c.Int(可空:假的,身份:真)
                    名称= c.String(可空:假),
                })
            .PrimaryKey(T => t.ID);        CREATETABLE(
            dbo.TrainingParticipant
            C =>新
                {
                    ID = c.Int(可空:假的,身份:真)
                    TrainingID = c.Int(可空:假),
                    ParticipantID = c.Int(可空:假),
                    Multiplier_ID = c.Int(),
                })
            .PrimaryKey(T => t.ID)
            .ForeignKey(dbo.Participant,T => t.ParticipantID)
            .ForeignKey(dbo.Training,T => t.TrainingID)
            .ForeignKey(dbo.Multiplier,T => t.Multiplier_ID)
            的.index(T => t.TrainingID)
            的.index(T => t.ParticipantID)
            的.index(T => t.Multiplier_ID);        CREATETABLE(
            dbo.Participant
            C =>新
                {
                    ID = c.Int(可空:假的,身份:真)
                    名称= c.String(可空:假),
                    姓= c.String(可空:假),
                    MultiplierID = c.Int(可空:假),
                })
            .PrimaryKey(T => t.ID)
            .ForeignKey(dbo.Multiplier,T => t.MultiplierID)
            的.index(T => t.MultiplierID);        CREATETABLE(
            dbo.Training
            C =>新
                {
                    ID = c.Int(可空:假的,身份:真)
                    名称= c.String(可空:假),
                    日期= c.DateTime(可空:假),
                    CityID = c.Int(可空:假),
                })
            .PrimaryKey(T => t.ID)
            .ForeignKey(dbo.City,T => t.CityID)
            的.index(T => t.CityID);        CREATETABLE(
            dbo.Region
            C =>新
                {
                    ID = c.Int(可空:假的,身份:真)
                    名称= c.String(可空:假),
                })
            .PrimaryKey(T => t.ID);    }



这是在migration.cs文件,向下的方法:

 公共覆盖无效向下()
    {
        DropForeignKey(dbo.City,RegionID,dbo.Region);
        DropForeignKey(dbo.TrainingParticipant,Multiplier_ID,dbo.Multiplier);
        DropForeignKey(dbo.TrainingParticipant,TrainingID,dbo.Training);
        DropForeignKey(dbo.Training,CityID,dbo.City);
        DropForeignKey(dbo.TrainingParticipant,ParticipantID,dbo.Participant);
        DropForeignKey(dbo.Participant,MultiplierID,dbo.Multiplier);
        DropForeignKey(dbo.Multiplier,InstituteStatusID,dbo.InstituteStatus);
        DropForeignKey(dbo.Multiplier,CityID,dbo.City);
        DropIndex(dbo.Training,新的[] {CityID});
        DropIndex(dbo.Participant,新的[] {MultiplierID});
        DropIndex(dbo.TrainingParticipant,新的[] {Multiplier_ID});
        DropIndex(dbo.TrainingParticipant,新的[] {ParticipantID});
        DropIndex(dbo.TrainingParticipant,新的[] {TrainingID});
        DropIndex(dbo.Multiplier,新的[] {InstituteStatusID});
        DropIndex(dbo.Multiplier,新的[] {CityID});
        DropIndex(dbo.City,新的[] {RegionID});
        DROPTABLE(dbo.Region);
        DROPTABLE(dbo.Training);
        DROPTABLE(dbo.Participant);
        DROPTABLE(dbo.TrainingParticipant);
        DROPTABLE(dbo.InstituteStatus);
        DROPTABLE(dbo.Multiplier);
        DROPTABLE(dbo.City);
    }


解决方案

你为什么这样做1-4步?这就是你出了问题。如果你有一个previously生成的数据库,你要做的仅仅是对架构更改,那么就产生迁移和应用它。通过这样做步骤1-4,你有效地撤消该数据库的实体框架的知识,基本上与code-先用现有的数据库结束了。在这一点上,你要么必须手动更改您的架构,或者让实体框架吹出来并重新开始。

至于又回到了那里你可以申请迁移的状态再次熄灭,你是在正确的轨道与产生迁移,只是走光了最多方法上。但是,你需要做的这对你的应用程序的previous状态,即该数据库匹配,因为它是目前之一。否则,实体框架是要生成创建表,包括你的code的变化。因此,要遵循的步骤是:


  1. 恢复您的code到时候你开始修改您的波苏斯之前。

  2. 生成迁移。

  3. 最多方法删除一切

  4. 应用与迁移更新数据库

  5. 重新应用你到你波苏斯所做的更改。

  6. 生成另一个迁移(这个应该现在只是有加/修改列报表,而不是创建表)

  7. 应用迁移。

在这之后,你应该是好着呢。然后,接下来你做code变化时,只要按照步骤5和6。

In my MVC application I used Entity Framework 6 and created database with code first approach. After a certain time, I updated one of the entity classes by adding new column and removing some columns. For reflecting these changes to the database I followed the steps below:

  1. Deleted the migrations folder in the project.
  2. Deleted the __MigrationHistory table in the database.
  3. Then run the following command in the Package Manager Console:
    Enable-Migrations -EnableAutomaticMigrations -Force

  4. Add the following lines in configuration file:
    AutomaticMigrationsEnabled = true;
    AutomaticMigrationDataLossAllowed = true;

  5. Run:
    Add-Migration Initial

  6. And finally, run:
    Update-Database -Verbose

However, I encounter an error "There is already an object named 'xxx' in the database."

To get rid of this problem, I comment the code in the Up method in the initial file created after 5th step. This prevent the error but nothing is changed in the database (the updated entity tables remains as before). Where is the mistake? Thanks in advance for your help.

Here is the Up method that I commented in the migration.cs file:

    public override void Up()
    {
        CreateTable(
            "dbo.City",
            c => new
                {
                    ID = c.Int(nullable: false, identity: true),
                    Name = c.String(nullable: false),
                    RegionID = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.ID)
            .ForeignKey("dbo.Region", t => t.RegionID)
            .Index(t => t.RegionID);

        CreateTable(
            "dbo.Multiplier",
            c => new
                {
                    ID = c.Int(nullable: false, identity: true),
                    Status = c.Int(nullable: false),
                    Term = c.Int(nullable: false),
                    CityID = c.Int(nullable: false),
                    WhoIsOnline = c.String(nullable: false),
                    UserId = c.String(nullable: false),
                    InstituteName = c.String(nullable: false),
                    InstituteStatusID = c.Int(nullable: false),
                    InstituteAccreditationDate = c.DateTime(nullable: false),
                    Address = c.String(nullable: false),
                    Phone = c.String(nullable: false),
                    Fax = c.String(),
                    Email = c.String(nullable: false),
                    EurodeskEmail = c.String(nullable: false),
                    WebSite = c.String(),
                    ContactName = c.String(nullable: false),
                    ContactSurname = c.String(nullable: false),
                    ContactJobTitle = c.String(),
                    ContactAssignmentDate = c.DateTime(),
                    ContactWorkingStart = c.String(),
                    ContactWorkingkEnd = c.String(),
                    ContactPhone = c.String(),
                    ContactMobile = c.String(nullable: false),
                    ContactEmail = c.String(nullable: false),
                    ContactCityID = c.Int(nullable: false),
                    LegalRepresentativeName = c.String(nullable: false),
                    LegalRepresentativeSurname = c.String(nullable: false),
                })
            .PrimaryKey(t => t.ID)
            .ForeignKey("dbo.City", t => t.CityID)
            .ForeignKey("dbo.InstituteStatus", t => t.InstituteStatusID)
            .Index(t => t.CityID)
            .Index(t => t.InstituteStatusID);

        CreateTable(
            "dbo.InstituteStatus",
            c => new
                {
                    ID = c.Int(nullable: false, identity: true),
                    Name = c.String(nullable: false),
                })
            .PrimaryKey(t => t.ID);

        CreateTable(
            "dbo.TrainingParticipant",
            c => new
                {
                    ID = c.Int(nullable: false, identity: true),
                    TrainingID = c.Int(nullable: false),
                    ParticipantID = c.Int(nullable: false),
                    Multiplier_ID = c.Int(),
                })
            .PrimaryKey(t => t.ID)
            .ForeignKey("dbo.Participant", t => t.ParticipantID)
            .ForeignKey("dbo.Training", t => t.TrainingID)
            .ForeignKey("dbo.Multiplier", t => t.Multiplier_ID)
            .Index(t => t.TrainingID)
            .Index(t => t.ParticipantID)
            .Index(t => t.Multiplier_ID);

        CreateTable(
            "dbo.Participant",
            c => new
                {
                    ID = c.Int(nullable: false, identity: true),
                    Name = c.String(nullable: false),
                    Surname = c.String(nullable: false),
                    MultiplierID = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.ID)
            .ForeignKey("dbo.Multiplier", t => t.MultiplierID)
            .Index(t => t.MultiplierID);

        CreateTable(
            "dbo.Training",
            c => new
                {
                    ID = c.Int(nullable: false, identity: true),
                    Name = c.String(nullable: false),
                    Date = c.DateTime(nullable: false),
                    CityID = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.ID)
            .ForeignKey("dbo.City", t => t.CityID)
            .Index(t => t.CityID);

        CreateTable(
            "dbo.Region",
            c => new
                {
                    ID = c.Int(nullable: false, identity: true),
                    Name = c.String(nullable: false),
                })
            .PrimaryKey(t => t.ID);

    }


And this is the Down method in the migration.cs file:

    public override void Down()
    {
        DropForeignKey("dbo.City", "RegionID", "dbo.Region");
        DropForeignKey("dbo.TrainingParticipant", "Multiplier_ID", "dbo.Multiplier");
        DropForeignKey("dbo.TrainingParticipant", "TrainingID", "dbo.Training");
        DropForeignKey("dbo.Training", "CityID", "dbo.City");
        DropForeignKey("dbo.TrainingParticipant", "ParticipantID", "dbo.Participant");
        DropForeignKey("dbo.Participant", "MultiplierID", "dbo.Multiplier");
        DropForeignKey("dbo.Multiplier", "InstituteStatusID", "dbo.InstituteStatus");
        DropForeignKey("dbo.Multiplier", "CityID", "dbo.City");
        DropIndex("dbo.Training", new[] { "CityID" });
        DropIndex("dbo.Participant", new[] { "MultiplierID" });
        DropIndex("dbo.TrainingParticipant", new[] { "Multiplier_ID" });
        DropIndex("dbo.TrainingParticipant", new[] { "ParticipantID" });
        DropIndex("dbo.TrainingParticipant", new[] { "TrainingID" });
        DropIndex("dbo.Multiplier", new[] { "InstituteStatusID" });
        DropIndex("dbo.Multiplier", new[] { "CityID" });
        DropIndex("dbo.City", new[] { "RegionID" });
        DropTable("dbo.Region");
        DropTable("dbo.Training");
        DropTable("dbo.Participant");
        DropTable("dbo.TrainingParticipant");
        DropTable("dbo.InstituteStatus");
        DropTable("dbo.Multiplier");
        DropTable("dbo.City");
    }

解决方案

Why did you do steps 1-4? That's where you went wrong. If you had a previously generated database and you're just making changes to the schema, then just generate a migration and apply it. By doing steps 1-4, you're effectively undoing Entity Framework's knowledge of this database and essentially ending up with code-first with an existing database. At which point, you either have to manually change your schema or let Entity Framework blow it out and start over.

As far as getting back to a state where you can apply migrations again goes, you were on the right track with generating a migration and just emptying out the Up method. However, you need to do this against your application's previous state, i.e. the one that matches the database as it currently is. Otherwise, Entity Framework is going to generate create tables that include your code changes. So the steps to follow are:

  1. Revert your code to the point before you started modifying your POCOs.
  2. Generate a migration.
  3. Remove everything in the Up method
  4. Apply the migration with update-database
  5. Re-apply the changes you made to your POCOs.
  6. Generate another migration (this one should now just have add/alter column statements instead of create tables)
  7. Apply the migration.

After that, you should be good to go again. Then, the next time you make code changes, just follow steps 5 & 6.

这篇关于更新与实体框架code首先在MVC现有数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆