Code-First 創建領域類
與DBFirst不同的而是,我們不需要先建立數據庫,而是先開始寫類。根據我們的需要,我們在EF_CoreDomain中先創建兩個簡單的Question
類和Option
類。如下所示:
Question類
public class Question
{
//id主鍵
public int QuestionId { get; set; }
//問題描述
public string QuestionDesc { get; set; }
//問題類型:單選題,多選題,判斷題等等
public string QuestionType { get; set; }
//答案
public string Answer { get; set; }
public bool IsDeleted { get; set; }
//選項
public ICollection<Option> Options { get; set; }
}
當時這個類的QuestionId 我命名為QID ,在運行最後的web程序的時候,添加數據會報錯沒有主鍵,我重新命名為類名+Id就通過了,Option類也遇到同樣的問題。(__) 後面會有答案哦。
Option 類
public class Option
{
public int OptionId { get; set; }
//選項描述
public string OptionDesc { get; set; }
public int QuestionId { get; set; }
//對應的問題
public Question Question { get; set; }
}
現在,我們已經為在線應用考試程序建立好了初始領域類。Code-First方法也需要繼承[DbContext](http:/7/1/2016 2:31:05 PM /www.entityframeworktutorial.net/EntityFramework4.3/dbcontext-vs-objectcontext.aspx)的上下文類。
Code-First 創建上下文類
接下來在EF_EntityFrameWork項目中建立上下文類,該類繼承DbContext類,具有用公共DbSet屬性,DbSet泛型結構是你所需要的領域類,比如Question和Option類,在這種情況下,DbSet是一個實體類的集合(又稱實體集),因此我們命名屬性名稱通常使用實體名稱的複數形式,比如Quesitons和Options
如果在你的類型沒有做數據注釋Table屬性或者沒有FluntAPI配置表名信息,默認的數據庫對應的表名稱既是上述的屬性名稱。
本例子中的表明通過DataAnnotation獨立命名。
public class QuestionContext:DbContext
{
public QuestionContext()
: base("EF_CodeFirst")
{
}
public DbSet<Question> Questions { get; set; }
public DbSet<Option> Options { get;set;}
}
創建數據庫連接
在web項目的webconfig文件中的configuration
節點中加入如下字符串連接。
<connectionStrings>
<add name="EF_CodeFirst" connectionString="Server=(local);Database=EF_CodeFirst;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
</connectionStrings>
在其他應用程序中可能是appconfig,按照項目類型不同配置文件名稱可能不同。
運行程序。
在空的MVC項目中,應用前面所提到的兩個項目,建立默認訪問的控制器以及視圖(這些內容請參考MVC,不再概述)。代碼如下:
public ActionResult Index()
{
using (var ctx = new QuestionContext())
{
Question qs = new Question()
{
QuestionDesc = "test()",
QuestionType = "單選題",
Answer = "A"
};
ctx.Questions.Add(qs);
ctx.SaveChanges();
Option op = new Option()
{
OptionDesc = "A.1",
QuestionId = qs.QuestionId,
};
Option op1 = new Option()
{
OptionDesc = "B.2",
QuestionId = qs.QuestionId,
};
Option op2 = new Option()
{
OptionDesc = "C.3",
QuestionId = qs.QuestionId,
};
Option op3 = new Option()
{
OptionDesc = "D.4",
QuestionId = qs.QuestionId,
};
ctx.Options.Add(op);
ctx.Options.Add(op1);
ctx.Options.Add(op2);
ctx.Options.Add(op3);
ctx.SaveChanges();
}
return View();
}
}
按照領域驅動設計來說,Web展現層是不應該直接引用領域層,而是應該通過應用層去訪問,不過本例子重在說明EFCode-First功能,暫時就這樣使用。
F5運行程序,程序正常運行并跳轉到首頁視圖界面。你也會非誠驚訝的發現,這些數據已經成功插入到數據庫。
但是,數據庫在哪?對應表及它的字段是什麼?
這就是實體框架代碼優先API的魅力所在。它根據你傳遞到上下文基類的構造函數的參數自動創建數據庫,即使你沒有傳遞任何參數給上下文類的構造函數,它會自動在本機SQLEXPRESS數據庫創建"項目名稱.上下文類名稱"的數據庫。本例數據表結構如下:
在上圖中可以看出,它在數據庫中創建了兩張表,dt_Question和dt_Option.這兩張表是基於上面所定義的Question和Options領域類來創建的。
正如上面截图所看到的,它創建了包含了適當數據類型及長度的字段的兩張數據表。字段的名稱和數據類型與各自對應的領域類向匹配。它也設置了各自表的主鍵,同時在dt_Option表中設置QuestionId 為外鍵。
用這種方法,無需先創建數據庫,你可以直接開始寫程序,最終通過你的領域類來創建數據庫。
你一定會有疑問,它是如何創建字段,如何設置適當的數據類型和長度,如何創建主鍵和外鍵,對不對?答案就是:Code-First的約定