6.翻譯系列:EF 6 Code-First中數據庫初始化策略(EF 6 Code-First系列)

       原文連接:http://www.entityframeworktutorial.net/code-first/database-initialization-strategy-in-code-first.aspxhtml

 

EF 6 Code-First系列文章目錄:數據庫

 

   

   當你第一次運行Code-First應用程序的時候,EF就會爲咱們建立數據庫,可是,後面呢,第二次第三次..的時候會是什麼狀況?是否是每次運行程序的時候,都會建立一個新的數據庫?生產環境中會是什麼狀況?當你改變你的領域模型的時候,你怎麼修改數據庫呢?爲了解決這些狀況,你須要來使用數據庫初始化策略。app

       EF 6中,有四種不一樣的數據庫初始化策略:ide

  1. CreateDatabaseIfNotExists:這是默認的數據庫初始化策略。就像它的名稱那樣,若是根據配置,數據庫不存在的話,就會建立數據庫。可是若是你改變模型類,使用這個策略,再運行程序的話,就會拋出一個異常。
  2. DropCreateDatabaseIfModelChanges:這個策略會在你的模型發生改變的時候,刪除已經存在的數據庫,而後建立一個新的數據庫。因此當你模型改變的時候,沒必要擔憂怎麼來維護數據庫對象模式。
  3. DropCreateDatabaseAlways:就像其名稱所示,這個策略每次你運行程序的時候,都會刪除以及存在的數據庫,而無論你的模型類 是否發生改變。這個策略很是有用,當你每次運行程序,都想要一個新的數據庫的時候。例如:當你在開發程序的時候。使用這個策略比較好。
  4. Custom DB Initializer: 若是上面的策略不知足你的需求或者數據庫初始化的時候,你想額外作一些其餘的處理的時候, 你就能夠建立你本身的數據庫初始化策略。

爲了使用上面提到的4個數據庫初始化策略,你能夠在上下文類中,使用Database類,例以下面代碼:學習

你若是想使用自定義的數據庫初始化策略,就能夠繼承上面三個中的其中一個策略,例如:測試

在上面的代碼中,SchoolDBInitiallizer就是一個自定義的數據庫初始化策略類,它繼承自CreateDatabaseIfNotExists。這種作法,將初始化策略代碼從上下文類中分離開來了。ui

 在配置文件中建立數據庫初始化策略spa

你一樣能夠在配置文件中,設置數據庫初始化策略。例如,下面代碼在配置文件中設置了默認的初始化策略--CreateDatabaseIfNotExists。.net

<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="DatabaseInitializerForType SchoolDataLayer.SchoolDBContext, SchoolDataLayer" value="System.Data.Entity.DropCreateDatabaseAlways`1[[SchoolDataLayer.SchoolDBContext, SchoolDataLayer]], EntityFramework" /> </appSettings> </configuration>

你能夠按照下面設置自定義的初始化策略:翻譯

<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="DatabaseInitializerForType SchoolDataLayer.SchoolDBContext, SchoolDataLayer" value="SchoolDataLayer.SchoolDBInitializer, SchoolDataLayer" /> </appSettings> </configuration>

關閉數據庫初始化策略

你能夠爲應用程序關閉數據庫初始化策略。假設你不想丟失生產環境的數據,你能夠按照下面的設置,關閉數據庫初始化策略:

一樣你能夠經過,配置文件來關閉數據庫初始化策略:

<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="DatabaseInitializerForType SchoolDataLayer.SchoolDBContext, SchoolDataLayer" value="Disabled" /> </appSettings> </configuration>

 

 好了,理論介紹完了,咱們何不動手實踐一下呢?

這裏我建立一個名稱爲EFDbInitializer控制檯應用程序,安裝好EF 6,來驗證今天所學:

爲了簡單起見,我只建立一個Student類,和一個上下文類:

 public class Student { /// <summary> /// 學生ID /// </summary> public int StudentID { get; set; } /// <summary> /// 學生姓名 /// </summary> public string StudentName { get; set; } /// <summary> /// 學生年齡 /// </summary> public int Age { get; set; } /// <summary> /// 郵箱 /// </summary> public string Email { get; set; } /// <summary> /// 性別 /// </summary> public Gender Gender { get; set; } } public enum Gender { /// <summary> /// 男士 /// </summary> Man=0, /// <summary> /// 女士 /// </summary> Woman=1 }
Student
 public class EFDbContext:DbContext { public EFDbContext() : base("name=Constr") { } public DbSet<Student> StuentTable { get; set; } }
上下文類的代碼

數據庫配置信息:

 <!--數據庫鏈接字符串--> <connectionStrings> <add name="Constr" connectionString="server=.;database=EFInitiallizerDB;uid=sa;pwd=Password_1" providerName="System.Data.SqlClient"/> </connectionStrings>

測試代碼:

 class Program { static void Main(string[] args) { using (var db = new EFDbContext()) { Student stuModel = new Student() { StudentName="曹雪芹", Age=18, Gender=Gender.Man, Email="caoxueqin@163.com" }; db.Entry(stuModel).State = EntityState.Added; db.SaveChanges(); } Console.WriteLine("success"); Console.ReadKey(); } }

運行程序:

說明建立數據庫成功了,裏面咱們插入了一條記錄。咱們看看:

從圖中能夠看到,EF默認生成的表名稱就是實體名稱+一個後綴s.默認映射實體中全部的屬性。【注意:只映射有get;set;的屬性哦

如今,咱們用這個數據庫,來驗證一下今天所學:

 修改上下文類:加一句代碼,以下標識:

而後運行程序:

看到又成功了,注意,數據庫中以前有一條數據,如今咱們應用了這個DropCreateDatabaseAlways策略,那麼數據庫中仍是會只有一條數據的,不信咱們看:

 

在來驗證一下,CreateDatabaseIfNotExists策略,修改一下上下文類中的代碼:

運行程序:

 

 成功了,這個時候,請注意:數據庫中應該是有兩條數據的,由於數據庫已經存在了,應用這個策略以後,EF不會再刪除數據庫,從新建立。咱們看看:

再驗證一下DropCreateDatabaseIfModelChanges策略,

咱們修改一下Student實體,新增一個Password字段。

 

 而後修改一下上下文類:

運行程序:

看到了麼,又成功了,這個時候,數據庫應該只有一條語句,由於咱們模型改變了,Students表應該還多了一個Password列。咱們看看:

 

好了,如今咱們來驗證一下,自定義的數據庫初始化策略。

建立一個自定義的數據庫初始化策略類,繼承自:DropCreateDatabaseIfModelChanges

 /// <summary> /// 自定義數據庫初始化策略類 /// </summary> public class CustomeDBInit: DropCreateDatabaseIfModelChanges<EFDbContext> { protected override void Seed(EFDbContext context) { Student stuModel = new Student() { StudentName="貂蟬", Age=20, Gender=Gender.Woman, Password="*******", Email="diaochan@163.com" }; context.Entry(stuModel).State = EntityState.Added; context.SaveChanges(); } }

而後修改Student實體,新增一個QQ屬性。

在修改一下測試代碼:

 

修改一下上下文類的代碼:

 

運行程序:

 

 

 

 成功了,咱們看看數據庫,這個時候數據庫有數據麼,大家猜猜???有數據的話,有幾條數據呢???答案是一條數據,就是我在自定義數據庫初始化策略中添加的一條。

 

 

 如今,咱們來驗證一下,咱們如何在配置文件中,配置咱們的數據庫初始化策略:

個人項目的命名空間是:EFDbInitializer,配置的要點就是DatabaseInitializerForType 命名空間.上下文類,命名空間,value值就是:命名空間.自定義的數據庫初始化策略類,命名空間。

而後修改一下上下文類:

運行程序:

看看數據庫:

不相信配置文件配置的這個策略被執行了的話,咱們刪除數據庫,而後修改實體看看:

1.刪除數據庫

2.修改一下實體:註釋QQ屬性

3.修改上下文類:

配置文件仍是這樣:

運行程序:

看看數據庫發生了什麼:能夠看到QQ列不見了,仍是有一條數據,咱們在自定義類中添加的,說明配置文件成功了配置數據庫初始化策略。

 

好了,最後看看,怎麼關閉數據庫初始化策略吧:

1.取消註釋QQ屬性:

 

 2.修改自定義的初始化策略類:

3.運行程序:

看,報錯了哦,這是由於咱們使用CreateDatabaseIfNotExists策略的時候,若是實體模型發生改變的話,就會拋異常,這個異常能夠經過,數據庫遷移技術解決,還能夠經過關閉數據庫初始化策略解決,這裏我採用第二種解決方法。

關閉數據庫策略。

修改上下文類:

運行程序:

咦,怎麼仍是報錯呢??原來配置文件中,還沒註釋掉呢,咱們註釋一下:

 

 再運行,咦,又報錯了,這是錯誤不同哦,QQ列名無效,哦,明白了, 關閉策略以後,咱們就不會再建立數據庫了,【這個時候,咱們自定義的策略類是CreateDatabaseIfNotExists,數據庫已經存在就不會刪除建立】,然而QQ這一個屬性還在Student實體中,EF就會要映射到數據庫,這就衝突了,咱們註釋QQ屬性。

 註釋QQ屬性,在運行:

看,成功了吧,是否是很爽?咱們看看數據庫:

 

好了,上面就是咱們今天學習的所有內容,數據庫初始化策略,有不明白的,能夠留言,我會一一回復,謝謝支持。

相關文章
相關標籤/搜索