我正在尝试让Entity框架迁移工作。我已启用代码首次迁移,它创建了迁移文件夹,配置文件和迁移历史记录表,但没有初始创建。我错过了一步吗?这是由EF(4.3.1)创建的新数据库。
答案 0 :(得分:21)
默认情况下,此行为不存在,但您可以通过多种不同的形式轻松使用它。
您可以在应用程序启动时调用context.Database.CreateIfNotExists();
。
您可以使用其中一个内置DatabaseInitializer
。 CreateDatabaseIfNotExists
初始化程序内置于EntityFramework中,只需添加到您的项目中。
您可以创建自己的自定义数据库初始化程序,其中包含选项#1。示例:Code First Migrations and initialization
您可以通过代码或配置文件在项目中包含DatabaseInitializers。
通过代码
包含EntityFramework数据库初始化程序在您的应用程序启动中,您可以像这样设置DatabaseInitializer:
System.Data.Entity.Database.SetInitializer<DairyMmmContext>(new System.Data.Entity.CreateDatabaseIfNotExists<DairyMmmContext>());
注意:此代码在entityframework的整个生命周期中已多次更改!此示例适用于EF 4.3,这是通过nuget提供的当前生产版本。
通过配置元素包含EntityFramework数据库初始化程序:
<configuration>
<entityFramework>
<contexts>
<context type="MyNamespace.MyEFDataContext, AssemblyName">
<databaseInitializer
type="System.Data.Entity.CreateDatabaseIfNotExists`2[[MyNamespace.MyEFDataContext, AssemblyName],
[MyNamespace.Migrations.Configuration, AssemblyName]], EntityFramework" />
</context>
</contexts>
</entityFramework>
</configuration>
你会注意到这可能是一点点&#34; ungraceful&#34;使用此配置。您需要将上面的AssemblyName
替换为保存实体框架内容的程序集的名称,将MyNamespace.MyEFDataContext
替换为entityframework数据上下文的完全限定名称,并将MyNamespace.Migrations.Configuration
替换为完全配置类的限定名称(默认位于项目内的“迁移”文件夹中)。
编辑:已编辑以回复其他评论
迁移是从一个模式定义到另一个模式定义的更改。创建空数据库不是迁移(但之后的所有内容都是)。项目中没有用于创建空数据库的迁移源文件,这是由初始化程序在代码中完成的。
如果您已经在使用DropCreateDatabaseAlways
初始化程序,那么应该这样做。但是,我注意到你在代码中设置了初始化程序,这意味着存在计时问题的机会(在你的上下文已经超过调用任何初始化程序之后设置初始化程序)。
您可以强制entityframework在context.Database.Initialize(true);
的代码中的任何位置运行初始化程序(该参数为true / false以强制初始化,而不管当前状态如何)。每次都会丢弃并重新创建数据库。
但您也可以确保在应用程序的生命周期中尽早设置初始化程序(在创建上下文的单个实例之前)。
答案 1 :(得分:17)
“初始创建”不是自动创建的!你需要自己创造。 EF的一些教程令人困惑,我和你有同样的误解。
您需要做什么:
-Add-Migration InitialModel
如果您已经创建了数据库表和域模型,那么:
-Add-Migration InitialModel -IgnoreChanges
从这一点开始,您的代码将与数据库同步。无论何时更改代码,都可以使用Add-Migration将更改添加到数据库中。
答案 2 :(得分:9)
这里的文章/教程here (on microsoft.com) 描述了initialCreate迁移不存在的原因。只有在数据库已存在的情况下才会添加迁移。否则,第一次迁移将是'initialCreate',因为创建迁移到尚不存在的数据库是没有意义的...没有数据库意味着在向下迁移时没有任何内容可以回滚。
以下是相关段落:
在程序包管理器控制台中运行Enable-Migrations命令 此命令已将Migrations文件夹添加到我们的项目中,此新文件夹包含两个文件:
Configuration类。此类允许您配置迁移对上下文的行为方式。在本演练中,我们将使用默认配置。 由于项目中只有一个Code First上下文,因此Enable-Migrations已自动填充此配置适用的上下文类型。
InitialCreate迁移。生成此迁移是因为在启用迁移之前,我们已经为Code First创建了一个数据库。此scaffolded迁移中的代码表示已在数据库中创建的对象。在我们的例子中,这是具有BlogId和Name列的Blog表。文件名包含一个时间戳,以帮助订购。
如果尚未创建数据库,则不会将此InitialCreate迁移添加到项目中。相反,我们第一次调用Add-Migration时,创建这些表的代码将被搭建到新的迁移中。
答案 3 :(得分:4)
不确定它是一样的,但我遇到了类似的问题。我认为我的问题与我不使用配置文件中的连接字符串来获取我的连接字符串这一事实有关。
摆弄解决方案中的启动项目以及Package Manager控制台中的projet组合,我能够生成第一次迁移。
还要确保您拥有一个带有dbContext类名称的连接字符串,以便程序包管理器可以找到它。
答案 4 :(得分:0)
我正在使用EF 6 RC1并遇到了这个问题,即运行Enable-Migrations时没有创建InitialCreate和__MigrationHistory。
实际上,在从EF 5升级到EF 6后,我运行了Enable-Migrations,由于某种原因,它使用EF 5架构创建了一个__MigrationHistory表,所以我删除了它和我的Migrations目录并试图重新开始。
但每次删除Migrations目录时,都不会创建InitialCreate或__MigrationHistory。我尝试删除并重新创建数据库并重新启动Visual Studio 2012无济于事。我放弃了这一天,第二天早上又试了一次 - 让我的电脑静置了大约8个小时后再创建了InitialCreate。我猜测某个地方必须有一个缓存超时 - 任何人?我也猜测重启可能会清除缓存,但我没试过。
无论如何,都可以使用PM> Add-Migration InitialCreate
手动执行该步骤。
无论如何,我仍然没有得到__MigrationHistory表。显然,EF 6已从在Enable-Migrations命令期间创建它变为仅在Update-Database命令期间创建它。由于我的架构已经在那时创建,我需要将其拆除并手动重新创建:
PM> Update-Database -TargetMigration:0
PM> Update-Database
我也在第一个检查数据库状态的命令后停止,以确保我正在更新正确的数据库,因为according to this,数据库连接字符串被拾取或自动生成,具体取决于配置,除非它如果配置正确,则无法保证您将访问您想要的SQL Server数据库或实例。
在运行这两个命令之后,它创建了一个__MigrationHistory表 - 并且它没有将它创建为系统表(我真的不想要它),所以一切都很好。与OP不完全相同的问题,但希望这对其他人有帮助。
参考文献:
答案 5 :(得分:0)
我知道这已经过时了,但没有接受的答案,我也有同样的问题。
技巧是Enable-Migrations命令。如上所述here,有一个命令启用 - 迁移-EnableAutomaticMigrations 。它的作用就是准确地开始迁移。
如果您希望第一次迁移是创建数据库,只需运行启用 - 迁移(不使用--EnableAutomaticMigrations)。
请记住设置初始化程序:
Database.SetInitializer(new MigrateDatabaseToLatestVersion<LicenseContext, Configuration>());