使用现有数据库的实体框架代码优先迁移策略 [英] Entity framework code first migration strategy with existing database

查看:69
本文介绍了使用现有数据库的实体框架代码优先迁移策略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下情况,无法确定正确的迁移策略。感谢帮助。

I have the following situation and unable to determine correct migration strategy. Help is appreciate.


  • 应用程序创建并将数据库用作数据存储

  • 应用程序需要更新数据库在启动时如果需要

  • 使用 Nuget Manager控制台是不可行的。 (出于迁移目的,在本地没有问题)

  • 我正在分发的数据库不是EF

  • Application creates and uses database as data storage
  • Application needs to update database on the start up if needed
  • using Nuget Manager console is not a option. (For migration purpose , locally no problem)
  • I Have existing database in distribution which are not EF

现在,我想开始使用EF代码优先方法。我需要实现的是:

Now I want to start using the EF code first approach. What I need to achieve is :


  1. 如果没有数据库,则创建一个

  2. 如果数据库存在,请使用空迁移(为下一次升级做好准备)

  3. 这应该在应用程序启动时发生

数据库不存在====>创建EF初始=====> Upg v1 =====> Upg V2

Database don't exists ====> Create EF Initial =====> Upg v1 =====> Upg V2

数据库已存在== ===>跳过初始版本,但准备进行下一次升级=====> Upg v1 ======> Upg v2

Database Exists =====> Skip Initial but be ready for next upgrades =====> Upg v1 ======> Upg v2

感谢您的帮助

其他信息:
这是存在的数据库(仅作为示例):

Additional info: This is database that exists (just an example):

CREATE DATABASE Test
GO

Use Test
GO
CREATE SCHEMA [TestSchema] AUTHORIZATION [dbo]
GO
CREATE TABLE [TestSchema].[Table1](
    [Id] [uniqueidentifier] NOT NULL,
    [Column1] [nvarchar](500) NOT NULL,
    [Column2] [bit] NOT NULL,
    [Column3] [bit] NOT NULL,
 CONSTRAINT [PK_MonitorGroups] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

使用逆向工程EF创建了初始迁移:

Using reverse engineering EF created initial migration :

public partial class Initial : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "TestSchema.Table1",
                c => new
                    {
                        Id = c.Guid(nullable: false),
                        Column1 = c.String(nullable: false, maxLength: 500),
                        Column2 = c.Boolean(nullable: false),
                        Column3 = c.Boolean(nullable: false),
                    })
                .PrimaryKey(t => t.Id);
        }

        public override void Down()
        {
            DropTable("TestSchema.Table1");
        }
    }

如果我使用@spender提供的代码对非现有数据库一切都很酷。
如果在现有数据库上使用它,直到更改模型(下一次迁移),它才起作用。

if I use the code provided by @spender against non existing database everything is cool . If I use it against existing database it works until i change the model (next migration).

我看到的是迁移返回的升级脚本包含整个数据库的创建。并且不能对已经存在的对象执行。

What I have seen is that upgrade script returned by migration contains entire database creation. And can not be executed against already existing objects.

实际可行的方法是将迁移表添加到现有数据库并添加初始数据,但是我不确定这是一个好的解决方案。

What can actually work is to add migration table to existing database and add initial data, but I am not sure that this is a good solution.

推荐答案

这花了我很多时间,所以我很乐意在这里分享。

This took a considerable while for me to figure out, so I'm happy to share it here.

因此,首先需要对数据库进行反向工程。 实体框架强大工具可以为您完成此任务。安装完成后,在您的项目中,使用nuget安装EF,在解决方案资源管理器中右键单击项目节点,然后在 Entity Framework -> Reverse Engineer Code首先。这将生成一堆模型类和到您项目的映射类。

So first you'll need to reverse engineer your database. Entity framework power tools can do this for you. Once it's installed, in your project, install EF with nuget, right click the project node in solution explorer, then Entity Framework -> Reverse Engineer Code First. This will generate a whole bunch of model classes and mapping classes to your project.

接下来,在Package Manager控制台中

Next, in Package Manager Console

Enable-Migrations

然后

Add-Migration Initial

以创建描述从空数据库到当前模式的过渡的迁移。

to create a migration that describes the transition from empty DB to the current schema.

现在,编辑生成的 Configuration.cs 类构造函数:

Now edit the generated Configuration.cs class constructor:

    public Configuration()
    {

        AutomaticMigrationsEnabled = false;
        AutomaticMigrationDataLossAllowed = false;
    }

接下来,在应用启动时,(也许在global.asax Application_Start (如果您是从网络服务器上运行的),则需要触发迁移。此方法将完成这项工作:

Next, at app startup, (so perhaps in global.asax Application_Start if you're running from a webserver), you need to trigger migrations. This method will do the job:

    public static void ApplyDatabaseMigrations()
    {
        //Configuration is the class created by Enable-Migrations
        DbMigrationsConfiguration dbMgConfig = new Configuration()
        {
            //DbContext subclass generated by EF power tools
            ContextType = typeof(MyDbContext)
        };
        using (var databaseContext = new MyDbContext())
        {
            try
            {
                var database = databaseContext.Database;
                var migrationConfiguration = dbMgConfig;
                migrationConfiguration.TargetDatabase =
                    new DbConnectionInfo(database.Connection.ConnectionString,
                                         "System.Data.SqlClient");
                var migrator = new DbMigrator(migrationConfiguration);
                migrator.Update();
            }
            catch (AutomaticDataLossException adle)
            {
                dbMgConfig.AutomaticMigrationDataLossAllowed = true;
                var mg = new DbMigrator(dbMgConfig);
                var scriptor = new MigratorScriptingDecorator(mg);
                string script = scriptor.ScriptUpdate(null, null);
                throw new Exception(adle.Message + " : " + script);
            }
        }
    }

现在您可以添加更多迁移像平常一样。应用运行时,如果尚未应用这些迁移,则将在调用 ApplyDatabaseMigrations 时应用它们。

Now you can add more migrations as normal. When the app runs, if these migrations haven't been applied, they will be applied when ApplyDatabaseMigrations is called.

现在您就在EF代码优先折叠中。我想这就是你问的,对吧?

Now you're right in the EF code-first fold. I think that's what you asked, right?

这篇关于使用现有数据库的实体框架代码优先迁移策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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