实体框架代码优先迁移策略与现有数据库
本文关键字:数据库 策略 迁移 框架 代码 实体 | 更新日期: 2023-09-27 18:23:50
我有以下情况,无法确定正确的迁移策略。感谢您的帮助。
- 应用程序创建数据库并将其用作数据存储
- 如果需要,应用程序需要在启动时更新数据库
- 使用NugetManager控制台不是一个选项。(出于迁移目的,本地没有问题)
- I现有数据库正在分发,但不是EF
现在我想开始使用EF代码优先的方法。我需要实现的是:
- 如果没有数据库,则创建一个
- 如果数据库存在,请使用空迁移(只是为下一次升级做好准备)
- 这应该在应用程序启动时发生
数据库不存在====>创建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代码的第一个折叠中。我想你就是这么问的,对吧?