我对Entity Framework 6.1.1中不同的迁移方法感到有些困惑
到目前为止,我的理解是我必须始终运行Update-Database
才能更新架构,以便它反映我新添加的模型。但是现在我设法创建了一个POCO模型,向DbSet<Foo> Foos {get;set;}
添加ApplicationDbContext
,重新构建应用程序,所有内容都神奇地起作用。
以前我记得必须运行Enable-Migrations
然后启用自动迁移并始终调用Update-Database
进行迁移,但似乎这不是必需的吗?
为了澄清一下,我使用了带有MVC和Internet身份验证的ASP.NET Web应用程序模板(只是脚手架生成的基本用户帐户)。
似乎有很多不同的迁移方法和许多教程,其中每个教程都有点不同,我不确定哪种方法实际上是正确的。我感觉我将可以分开的东西混合在一起。我在网上找到的大多数资源也引用了不同版本的EF和ASP.NET MVC。
根据我的POCO模型生成数据库模式所需的步骤是什么?是否有一种简单的方法可以根据需要自动重新创建和重新种子数据库,或者之后我必须继续使用Update-Database
吗?
我使用的是Visual Studio 2013 Ultimate,如果有任何相关性的话。
答案 0 :(得分:1)
我相信你在这里有多个问题,所以我会尽我所能解决这些问题。
首先:
我刚设法创建了一个POCO模型,添加了一个DbSet Foos {get; set;}到我的ApplicationDbContext,重新构建应用程序和 一切都神奇地起作用。
您的项目似乎已启用Automatic Code First Migrations。从提供的链接看,默认情况下似乎没有启用自动迁移,因此必须通过运行命令或使用自定义代码(稍后显示)来更改某些内容
如果你再次运行该应用程序,你会得到一个 InvalidOperationException声明支持&#39; BlogContext&#39; 自创建数据库以来,上下文已更改。考虑使用 Code First Migrations更新数据库( http://go.microsoft.com/fwlink/?LinkId=238269)。
如异常所示,是时候开始使用Code First了 迁移。因为我们想要使用自动迁移 指定-EnableAutomaticMigrations开关。
在中运行Enable-Migrations -EnableAutomaticMigrations命令 包管理器控制台
下一步:
能够生成数据库架构所需的步骤是什么 基于我的POCO模型?
嗯,你有几种选择; EF自动迁移,EF&#39;标准版&#39;迁移,第三方库迁移(FluentMigrator)。这本身就是一个广泛的问题。但任何和所有选项都是有效的,它只取决于您的需求。我目前正在为个人项目和FluentMigrator使用EF自动迁移。
最后:
是否有一种简单的方法可以重新创建和重新种子数据库 需要自动,或者我必须继续使用Update-Database 是什么?
你在这里想做什么是重要的问题。我很确定你不想在生产中删除和重新创建/重新设置数据库(虽然这是可能的)。
您可能希望使用某种 DBInitializer 来满足您的需求。这是我在几个月前研究这个时使用的tutorial。您有3个默认选项( CreateDatabaseIfNotExists , DropCreateDatabaseIfModelChanges , DropCreateDatabaseAlways ),当然也可以自定义您自己的选项。
另一个可用选项是编写自定义 DbMigrationsConfiguration 。我无法找到我读到的文章,但这里有一些示例代码。在这段代码中,我使用我的自定义配置类初始化了我的DBContext,其中我打开了EF自动迁移并使用一些默认数据填充我的数据库。
<强>的DbContext 强>
public ApplicationDBContext()
: base("DefaultConnection")
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<ApplicationDBContext, IBCF.Core.Migrations.Configuration>());
}
<强>配置强>
internal sealed class Configuration : DbMigrationsConfiguration<IBCF.Core.ApplicationDBContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(IBCF.Core.ApplicationDBContext context)
{
//Initialize managers
var userManager = new UserManager<User>(new UserStore<User>(context));
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
if(userManager.FindByEmail("john.doe@email.com") == null)
{
//Add default system roles
roleManager.Create(new IdentityRole("Superuser"));
roleManager.Create(new IdentityRole("User"));
//Add default system users
var superuser1 = new User() { FirstName = "John", LastName = "Doe", Email = "john.doe@email.com", UserName = "john.doe@email.com.com" };
if (userManager.Create(superuser1, "P@ssword123").Succeeded)
{
userManager.AddToRole(superuser1.Id, "Superuser");
}
}
context.SaveChanges();
}
}
答案 1 :(得分:1)
到目前为止,我的理解是我必须始终运行Update-Database以更新架构,以便它反映我新添加的模型。
您可以从Package Manager控制台,初始化程序或代码运行迁移。
PM> Update-Database
Database.SetInitializer(new MigrateDatabaseToLatestVersion<AppContext, Configuration>());
或DbMigrator(new Configuration()).Update()
new DbMigrator(new Configuration()).Update();
但是现在我设法创建了一个POCO模型,在我的ApplicationDbContext中添加了一个DbSet Foos {get; set;},重新构建了应用程序,一切都神奇地起作用。
如果您已退出数据库并且模型中有新的更改,例如通过添加新的DbSet<T>
或仅添加新属性,而无需设置任何初始化程序/迁移(在代码或配置中),您应该得到类似的错误。
支持'AppContext'上下文的模型自从以来发生了变化 数据库已创建。考虑使用Code First Migrations进行更新 数据库。
您可能已将某处设置为使用MigrateDatabaseToLatestVersion
并设置AutomaticMigrationsEnabled = true;
。
然后启用自动迁移并始终调用Update-Database进行迁移,但似乎这不是必需的吗?
是的,一旦启用自动迁移,就不再需要了。
根据我的POCO模型生成数据库架构所需的步骤是什么?
如果您想手动维护数据库版本:
DbMigrationsConfiguration<TContext>
的配置类,或者只使用PMC PM> Enable-Migrations
DbMigration
,或者只使用PMC PM> Add-Migration MigrationNameForVersioning
AutomaticMigrationsEnabled = false
MigrateDatabaseToLatestVersion
如果您只想自动更新数据库而不手动创建每个迁移版本。
DbMigrationsConfiguration<TContext>
的配置类,或者只使用PMC PM> Enable-Migrations
AutomaticMigrationsEnabled = true
MigrateDatabaseToLatestVersion
代码
internal sealed class Configuration : DbMigrationsConfiguration<AppContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
ContextKey = "AppContext"; // don't forget to match this key if create the class manually
}
protected override void Seed(AppContext context)
{
}
}
用法
Database.SetInitializer(
new MigrateDatabaseToLatestVersion<AppContext, Configuration>());
更多