在微軟官方關於ef7的介紹中強調,ef7將捨棄database first、model first,只保留code first的使用。這引起了很多人的擔憂,擔憂源自對code first的錯誤理解。因為很多人認為code first是區別於database first與model first的第三種方式,其實這是錯誤的理解。其實code first是替代前兩種方式的解決方案。換句話來說,Code First 不是相對 Database First 和Model First的第三種方式,而是一種可以替代EDMX文件格式的方案。從概念上講,Code First 同時支持Database First和Model First工作方式。 這的確讓人感到混亂,我們取錯了名字。 或許叫它“基於代碼建模(code-base modeling)”會更清晰些。這裡有一篇關於ef7的介紹文檔:https://msdn.microsoft.com/zh-cn/magazine/dn890367.aspx
1.首先為你的項目安裝上entityframework,然後右鍵你的項目,添加兩個實體類文件,類文件信息如下:
1 public class Class 2 { 3 public int Id { get; set; } 4 public string Name { get; set; } 5 public virtual List<Student> Students { get; set; } 6 public Class() 7 { 8 Students = new List<Student>(); 9 } 10 }
1 public class Student 2 { 3 //[Key] 4 public int Id { get; set; } 5 public string Name { get; set; } 6 public int ClassId { get; set; } 7 8 //[ForeignKey("ClassId")] 9 public virtual Class Class { get; set; } 10 }
1.2 在添加一個繼承自DbContext的類,DbContext類是ef的數據訪問核心。類信息如下:
1 public class MyEfRecipesContext:DbContext 2 { 3 public MyEfRecipesContext() 4 { 5 //Database.SetInitializer(new CreateDatabaseIfNotExists<MyEfRecipesContext>()); 6 } 7 public DbSet<Student> Students { get; set; } 8 public DbSet<Class> Classs { get; set; } 9 10 protected override void OnModelCreating(DbModelBuilder modelBuilder) 11 { 12 //這裡可以用於模型創建前的配置修改 13 } 14 }
上圖中的注釋代碼是可以省略的,因為ef的默認配置就是這樣。當然你可以手動更改配置信息。在ef中有一個原則“約定大於配置”,約定其實也就是默認配置,意思就是說ef中的約定最好不要主動去修改它。下面是ef的一些默認約定:
(1) 數據庫映射:Code First 默認會在本地的SQL Expression數據庫中建立一個和DbContext的子類的全名相同的數據庫,全名指的是命名空間加上類名。
(2)表映射:Code First 默認會按照類型名復數建立數據表,比如說Student類對應的表名就叫Students.
(3)列映射:Code First 默認會按照類中的屬性名建立column,它還有默認的數據類型映射習慣,int會映射為interger,string會映射為nvarchar(max),decimal會映射為decimal(18,2)。後邊會介紹如何更改column的名稱,類型以及其他特性。
(4)主鍵映射:Code First 默認會在類的屬性中需找名字為Id或類型名稱+Id的int類型的屬性作為主鍵,並且是自增字段。這些也是可以改的。
1.3 在App.config中添加配置文件,如果是Web程序配置文件則是Web.config,這個不用介紹了吧。連接字符串信息如下:
<connectionStrings> <add name="MyEfRecipesContext" connectionString="Data Source=.;Initial Catalog=myefrecipes;User Id=sa;Password=renjing2000;MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" /> </connectionStrings>
2.示例代碼。新增與查詢,輸出見圖5-1:
1 using (MyEfRecipesContext db = new MyEfRecipesContext()) 2 { 3 Class c1 = new Class() { Name = "class1" }; 4 Student s1 = new Student() { Name = "rj1", Class = c1 }; 5 Student s2 = new Student() { Name = "rj2", Class = c1 }; 6 7 db.Students.Add(s1); 8 db.Students.Add(s2); 9 int i = db.SaveChanges(); 10 11 Console.WriteLine("id\t姓名\t班級"); 12 foreach (var item in db.Students) 13 { 14 Console.WriteLine("{0}\t{1}\t{2}",item.Id,item.Name,item.Class.Name); 15 } 16 }
圖5-1
3.運行程序後,生成的表結構如圖5-2。可以發現Students表月Classes表生成了“一對多”的關系,和我們的預期一樣。“__MigrationHistory”是ef自動生成的一張表,主要用於ef的一些配置信息,可以不用關心。
圖5-2