2012-08-22 86 views
26

我試圖讓實體框架遷移工作。我已經啓用了代碼優先遷移,創建了遷移文件夾,配置文件和mig歷史記錄表,但沒有初始創建。我錯過了一個步驟?這是EF(4.3.1)創建的一個新數據庫。實體框架遷移沒有初始創建

+2

啓用遷移後,您必須添加遷移 – Dabblernl

+0

它不會在初始添加自動創建遷移? –

+2

這可能有助於http:// stackoverflow。com/questions/11679385/reset-entity-framework-migrations – detay

回答

21

此行爲在默認情況下不存在,但它很容易以多種不同的形式提供給您。

  1. 你可以在應用程序啓動時調用context.Database.CreateIfNotExists();

  2. 您可以使用其中一個內置的DatabaseInitializer s。初始化器內置到EntityFramework中,只需將其添加到項目中即可。

  3. 您可以創建自己的自定義數據庫初始值設定項,其中包含選項#1。示例:Code First Migrations and initialization

您可以通過代碼或配置文件在您的項目中包含DatabaseInitializers。

包括通過代碼的EntityFramework數據庫初始化程序:

在你的應用程序啓動時您可設置DatabaseInitializer像這樣:

System.Data.Entity.Database.SetInitializer<DairyMmmContext>(new System.Data.Entity.CreateDatabaseIfNotExists<DairyMmmContext>()); 

注意:在整個的EntityFramework的生活該代碼已經多次改變!此示例適用於通過nuget提供的當前產品版本EF 4.3。

包括通過配置元素的的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> 

你會發現這可能是一個有點「非正常」與此配置。您需要將上面的AssemblyName替換爲您保留實體框架內容的程序集的名稱,將MyNamespace.MyEFDataContext替換爲實體框架數據上下文的標準名稱,並用您的配置類的完全限定名替換MyNamespace.Migrations.Configuration(默認情況下爲遷移您的項目中的文件夾)。

編輯:編輯對補充意見

遷移響應是從一個架構定義的改變到另一個模式定義。創建空數據庫不是遷移(但是之後的所有內容都是)。您的項目中不會有任何遷移源文件用於創建一個空數據庫,這是由初始化程序在代碼中完成的。

如果您已經在使用DropCreateDatabaseAlways初始值設定項,它應該這樣做。但是,我注意到你正在設置代碼中的初始化器,這意味着有時機問題(在你的上下文已經超過調用任何初始化器的位置之後設置初始化器)。

您可以強制entityframework在context.Database.Initialize(true);(該參數是true/false來強制初始化,而不管當前狀態如何)代碼中的任何一點運行初始值設定項。每次都會丟棄並重新創建數據庫。

但你也可以只是確保你的初始化設置是儘可能早地在你的應用程序的生命週期(您已經創建了上下文的單個實例之前)。

+0

謝謝。我已經得到了它,所以當我的數據庫創建時觸發:Database.SetInitializer(新的DropCreateDatabaseAlways ());這不足以讓EF創建初始創建遷移文件嗎? –

+0

另外,它似乎第一個初始創建是一個自動遷移,不知道如果這就是爲什麼沒有遷移腳本,當我嘗試恢復到初始數據庫,它會恢復除初始創建這是一個自動遷移的所有遷移.. 。有任何想法嗎?我只在數據庫創建後啓用遷移 –

+0

@ newbie_86我通過修改我的答案來解決您的意見,因爲我認爲其他同樣存在問題的人可能也會從中獲益。 – BenSwayne

4

不知道它是相同的,但我也有類似的問題。我認爲我的問題與事實有關,我不使用配置文件中的連接字符串來獲取我的連接字符串。

與溶液中的啓動項目,也是在包管理器控制檯謨組合我是能夠產生第一次遷移擺弄。

也使舒爾你有一個連接字符串您的DbContext類的名稱,以便程序包管理器可以找到它。

9

這篇文章/教程here (on microsoft.com) 描述了initialCreate遷移不存在的原因。只有在數據庫已存在的情況下才會添加遷移。否則,第一次遷移將是'initialCreate',因爲創建遷移到尚不存在的數據庫沒有意義...沒有數據庫意味着沒有任何東西可以回滾到下遷移。

下面是相關的段落:

運行的軟件包管理器控制檯啓用的遷移命令 這個命令添加了一個遷移文件夾到我們的項目,這個新的文件夾包含兩個文件:

配置類。該類允許您配置Migrations對於您的上下文的行爲。對於本演練,我們將僅使用默認配置。 因爲僅僅是在你的項目中的單碼一背景下,啓用的遷移自動填充的這種配置適用於上下文類型。

InitialCreate遷移。這種遷移的產生是因爲我們已經讓Code First爲我們創建了一個數據庫,然後我們啓用了遷移。此腳手架遷移中的代碼表示已在數據庫中創建的對象。在我們的例子中,這是帶有BlogId和Name列的Blog表。文件名包含一個時間戳以幫助排序。

如果數據庫尚未創建,則此InitialCreate遷移將不會添加到項目中。相反,當我們第一次調用Add-Migration時,創建這些表的代碼將被架構到一個新的遷移。

0

我使用EF 6 RC1,跑進這個問題,其中既沒有InitialCreate也不__MigrationHistory運行啓用的遷移時正在創建的。

實際上,在從EF 5升級到EF 6之後,我運行了Enable-Migrations,並且由於某種原因它使用EF 5架構創建了__MigrationHistory表,因此我刪除了它和我的Migrations目錄並試圖重新開始。

但每次我刪除它不會創建一個InitialCreate或__MigrationHistory的遷移目錄的時間。我嘗試刪除並重新創建數據庫並重新啓動Visual Studio 2012無濟於事。我放棄了這一天,第二天早上又試了一次 - 讓我的電腦坐了大概8個小時,然後創建了InitialCreate。我猜測必須有一個超時時間很長的緩存 - 任何人?我也猜測重新啓動可能會清除緩存,但我沒有嘗試。

無論如何,都可以使用PM> Add-Migration InitialCreate手動完成該步驟。

無論如何,我仍然沒有得到一個__MigrationHistory表。顯然,EF 6已經從在啓用遷移命令期間創建它改爲在Update-Database命令期間創建它。而且,由於我的架構已經在這一點上創建的,我需要將其摧毀,並手動重新創建它:

PM> Update-Database -TargetMigration:0 
PM> Update-Database 

我也是第一次命令後停下來檢查數據庫的狀態,以確保我更新正確的一個,因爲according to this,數據庫連接字符串被拾取或自動生成,具體取決於配置,除非它被正確配置,否則不能保證您將訪問您打算訪問的SQL Server數據庫或實例。

運行這兩個命令後,它創建了一個__MigrationHistory表 - 它並沒有創建它作爲系統表(我真的不想要),所以一切都很好。與OP不完全相同的問題,但希望這會對其他人有所幫助。

參考文獻:

16

「初始創建」 未自動創建!你需要自己創建。 EF的一些教程令人困惑,我和你有同樣的誤解。

你需要做什麼:

-Add-Migration InitialModel 

如果您已經創建了數據庫表和領域模型,然後:

-Add-Migration InitialModel -IgnoreChanges 

從這一點來說,你的代碼將與數據庫同步。無論何時您更改代碼,都可以使用添加遷移將更改添加到數據庫。

+0

這解決了我的問題。 –

+0

對於擁有現有數據庫的人來說,絕對是最簡單的解決方案。 – JRadness

0

我知道這是舊的,但沒有接受的答案,我有同樣的問題。

訣竅是Enable-Migrations命令。如here所述,有一個命令Enable-Migrations -EnableAutomaticMigrations。它所做的事情就是開始遷移到你所在的位置。

如果您希望首次遷移爲創建數據庫,請運行Enable-Migrations(不帶--EnableAutomaticMigrations)。

並記得設置初始化:

  Database.SetInitializer(new MigrateDatabaseToLatestVersion<LicenseContext, Configuration>());