我只是在考虑为我们的项目使用 EF 迁移,特别是在版本之间执行生产中的架构更改。
我已经看到提到有一个 API 可以使用 DbMigration
类在运行时执行这些迁移,但我找不到任何具体示例。
理想情况下,我希望每个数据库更改都有一个 DbMigration
文件,并且这些更改会在应用程序从当前版本到最新版本启动时自动应用。
有一个 Database Initializer 可用于在启动时迁移到最新版本(或者更好的是,dbinitializer 将在第一次访问 db 时启动),MigrateDatabaseToLatestVersion
,您可以这样使用它:
Database.SetInitializer<ObjectContext>(
new MigrateDatabaseToLatestVersion<ObjectContext, Configuration>());
关于每次迁移只有一个文件,如果您启用自动迁移,您将在项目根目录的 Migrations
文件夹(默认情况下)中找到它们。
这也有效:
var configuration = new MyDbContextConfiguration();
configuration.TargetDatabase = new DbConnectionInfo(
database.ConnectionString, database.ProviderName);
var migrator = new DbMigrator(configuration);
migrator.Update();
您也可以致电:
migrator.GetPendingMigrations();
获取它需要应用的迁移列表。
database
是什么?
new DbConnectionInfo
部分。谢谢!
由于您没有指定您使用的 Visual Studio 版本或数据库,我将在此处添加一个答案,说明在 VS2015 中使用 Microsoft 的 SQL Server,现在使用“发布”工具非常容易。
您无需为您所说的 API 烦恼。只需在本地完成您的工作,更改您的模型,应用迁移等,然后当您想要推送到发布/测试服务器时,使用发布工具。
您可以选择在首次启动应用程序时将您在本地进行的任何迁移应用到远程服务器。
一旦您完成了所有迁移并在本地完成了所有操作(可能在您的开发环境中),然后您发布(右键单击项目,单击“发布...”勾选“执行代码优先迁移(在应用程序启动时运行)”复选框下“设置”选项卡,然后它将在第一次访问应用程序时应用迁移(因此第一次会有短暂的延迟)。
https://i.stack.imgur.com/kysUI.png
指南:https://msdn.microsoft.com/en-us/library/dd465337(v=vs.110).aspx
我学到了这一切,因为我必须对 Windows 2012 服务器执行此操作:http://www.sherweb.com/blog/how-to-install-webdeploy-on-windows-server-2012/
祝你好运!
File System
时不可用
我想控制哪些迁移在代码中显式运行,经过大量搜索后,我设法开发了以下技术,而无需 DbConfiguration 类或启用自动迁移:
public static void RunMigration(this DbContext context, DbMigration migration)
{
var prop = migration.GetType().GetProperty("Operations", BindingFlags.NonPublic | BindingFlags.Instance);
if (prop != null)
{
IEnumerable<MigrationOperation> operations = prop.GetValue(migration) as IEnumerable<MigrationOperation>;
var generator = new SqlServerMigrationSqlGenerator();
var statements = generator.Generate(operations, "2008");
foreach (MigrationStatement item in statements)
context.Database.ExecuteSqlCommand(item.Sql);
}
}
如果我们有这样的迁移:
public class CreateIndexOnContactCodeMigration : DbMigration
{
public override void Up()
{
this.CreateIndex("Contacts", "Code");
}
public override void Down()
{
base.Down();
this.DropIndex("Contacts", "Code");
}
}
我们会这样使用它:
using (var dbCrm = new CrmDbContext(connectionString))
{
var migration = new CreateIndexOnContactCodeMigration();
migration.Up();
dbCrm.RunMigration(migration);
}
问候。
添加到所有已发布的答案。 Entity Framework 使用表:dbo.__MigrationHistory 来跟踪已应用于数据库的所有迁移,以避免运行迁移,例如:插入数据或更改数据库架构。
如果您希望运行脚本,例如运行添加数据或更改数据库架构,您可以使用包管理器控制台创建一个空迁移并通过新添加的迁移运行脚本。确保使用初始化程序来防止 EF 在每次运行时删除和重新创建数据库。
public override void Up()
{
string directoryToSearchScripts = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\"));
string scriptFilePath = Directory.GetFiles(directoryToSearchScripts, "dummy-script.sql", SearchOption.AllDirectories).FirstOrDefault();
if (!string.IsNullOrEmpty(scriptFilePath))
{
string fundsSqlScript = File.ReadAllText(scriptFilePath);
Sql(fundsSqlScript);
}
}
public override void Down()
{
}
当您发布应用程序并选中“执行代码优先迁移”选项时,EF 将运行尚未应用于数据库的迁移。