1.什么是CodeFirst
從EF4.1開始,EF可以支持CodeFirst開發模式,這種開發模式特別適用於領域驅動設計(Domain Driven Design,大名鼎鼎的DDD)。在CodeFirst模式中,我們不再先創建數據庫,然后在程序中創建對應的類;CodeFirst開發模式中我們只關注應用程序的域(Domain)直接開始創建類,EF會根據我們創建的類自動生成數據庫。
CodeFirst的工作流程如下所示:
使用CodeFirst模式進行開發時,我們的開發流程是:創建/修改領域類-->配置領域類(使用Fluent API或者注釋屬性)-->新建/修改數據庫架構(使用自動遷移或者代碼遷移)
2.CodeFirst的簡單入門案例
添加一個名字為EF6Console的控制台應用程序,然后把EF引入到項目中,如下圖:
添加了EF后我們就可以就行EF的CoreFirst開發了
第一步:添加領域類
首先添加兩個Student和Grade類(學生和年紀),它們是一對多關系,一個年級有多個學生,而一個學生只能有一個年級,代碼如下:
public class Student { public int StudentID { get; set; } public string StudentName { get; set; } public DateTime? DateOfBirth { get; set; } public byte[] Photo { get; set; } public decimal Height { get; set; } public float Weight { get; set; } public Grade Grade { get; set; } }
public class Grade { public int GradeId { get; set; } public string GradeName { get; set; } public string Section { get; set; } public ICollection<Student> Students { get; set; } }
第二步:添加context上下文
CodeFirst模式也需要一個context上下文類,和DbFirst開發不同,在CodeFirst模式中context類需要我們自己創建,context類繼承DbContext,代碼如下:
public class SchoolContext : DbContext { //構造函數 public SchoolContext() : base() { } //每個類設置一個的DbSet屬性 public DbSet<Student> Students { get; set; } public DbSet<Grade> Grades { get; set; } }
完成了這兩步,SqlServer的CodeFirst簡單入門就結束了,是不是特別方便?
我們在程序中添加一個Student,代碼如下:
class Program { static void Main(string[] args) { using (var ctx=new SchoolContext()) { Student student = new Student() { StudentName = "bill" }; ctx.Students.Add(student); ctx.SaveChanges(); Console.WriteLine("初始化完成"); } } }
執行后數據庫就自動創建了,如下圖所示
因為沒有添加任何關於context的設置,所以EF安裝默認規則在vs內置的sqlserver中給我們創建了 數據庫,名字是EF6Console.SchoolContext(項目名.上下文名),同時給Student和Grade領域類生成了dbo.Students和dbo.Grades(dbo.class復數)表。表中的每個列對應類的屬性,后綴有Id(如studentId)的設置為主鍵和外鍵,實體實例生成了數據庫的記錄。當切換到CodeFirst開發時,感覺整個項目看起來都清爽了~
注意:這時如果修改類(如Student類)的話,運行程序時會拋出異常。如我們把Student類的體重屬性注釋了,如下所示
public class Student { public int StudentId { get; set; } public string StudentName { get; set; } public DateTime? DateofBirth { get; set; } public byte[] Photo { get; set; } public decimal Height { get; set; } //public float Weight { get; set; } public Grade Grade { get; set; } }
然后運行程序,出現
這時因為領域類(Student)改變了導致數據庫中dbo.Students表的列也要隨着改變,這就需要我們定義一個數據庫的遷移策略(database initialization strategy),在以后的章節會介紹。