我遇到以下情况,无法确定正确的迁移策略。帮助很感激。
现在我想开始使用EF代码第一种方法。我需要实现的是:
数据库不存在====>创建EF初始=====> Upg v1 =====> Upg V2
数据库存在=====>跳过初始但准备好进行下一次升级=====> Upg v1 ======> Upg 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提供的代码对不存在的数据库,一切都很酷。 如果我在现有数据库中使用它,它将一直有效,直到我更改模型(下一次迁移)。
我所看到的是,迁移返回的升级脚本包含整个数据库创建。并且不能对已有的对象执行。
实际上可以工作的是将迁移表添加到现有数据库并添加初始数据,但我不确定这是一个很好的解决方案。
答案 0 :(得分:17)
我花了很长时间才弄明白,所以我很乐意在这里分享。
首先,您需要对数据库进行逆向工程。 Entity framework power tools可以为您完成此操作。安装完成后,在项目中,使用nuget安装EF,右键单击解决方案资源管理器中的项目节点,然后Entity Framework
- > Reverse Engineer Code First
。这将为您的项目生成一大堆模型类和映射类。
接下来,在软件包管理器控制台中
Enable-Migrations
然后
Add-Migration Initial
创建描述从空DB到当前架构的转换的迁移。
现在编辑生成的Configuration.cs
类构造函数:
public Configuration()
{
AutomaticMigrationsEnabled = false;
AutomaticMigrationDataLossAllowed = false;
}
接下来,在应用启动时,(如果您从网络服务器运行,可能在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代码优先折叠中。我认为那就是你问的,对吧?