实体框架代码优先迁移策略与现有数据库

本文关键字:数据库 策略 迁移 框架 代码 实体 | 更新日期: 2023-09-27 18:23:50

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

  • 应用程序创建数据库并将其用作数据存储
  • 如果需要,应用程序需要在启动时更新数据库
  • 使用NugetManager控制台不是一个选项。(出于迁移目的,本地没有问题)
  • I现有数据库正在分发,但不是EF

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

  1. 如果没有数据库,则创建一个
  2. 如果数据库存在,请使用空迁移(只是为下一次升级做好准备)
  3. 这应该在应用程序启动时发生

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

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

感谢您的帮助

其他信息:这是存在的数据库(只是一个例子):

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创建初始迁移:

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提供的代码,那么一切都很酷。如果我对现有数据库使用它,它会一直工作,直到我更改模型(下一次迁移)。

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

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

实体框架代码优先迁移策略与现有数据库

我花了很长时间才弄清楚,所以我很高兴在这里分享它。

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

接下来,在Package Manager控制台中

Enable-Migrations

然后

Add-Migration Initial

以创建描述从空DB到当前模式的转换的迁移。

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

    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
        AutomaticMigrationDataLossAllowed = false;
    }

接下来,在应用程序启动时(因此,如果您从Web服务器运行,可能在global.asax Application_Start中),您需要触发迁移。这种方法可以完成任务:

    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时应用这些迁移。

现在您正处于EF代码的第一个折叠中。我想你就是这么问的,对吧?