entity framework-Code First Approach
阿新 • • 發佈:2018-12-27
開篇之前感謝 china_fucan的文章給我的幫助,下面的評論也解決了很多問題同樣給予感謝.
code first
專案中的ORM框架如果採用的是EF,那麼可能會採用code first的方式去使用EF.就是先將資料庫的實體類,以及EF的核心DBContext寫好之後, 執行程式會通過特定的資料庫連結字串在資料庫中生成相應的table或資料.
建立一個code first demo
- 使用vs新建一個console app
- 建立一個class命名為
Ef6RecipesContext
,並且繼承自DbContext
.
using System.Data.Entity; using DennisEFDemo.CodeFirstDemo.DBModels; namespace DennisEFDemo.CodeFirstDemo.DBContext { public class Ef6RecipesContext : DbContext { public DbSet<PictureCategory> PictureCategories { get; set; } public Ef6RecipesContext() : base("name=EF6CodeFirstRecipesContext") { } /// <summary> /// 在EF6RecipesContext中重寫方法OnModelCreating配置雙向關聯(ParentCategory 和 SubCategories) /// </summary> /// <param name="modelBuilder"></param> protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<PictureCategory>().HasMany(t => t.Subcategories).WithOptional(t => t.ParentCategory); } } }
- 建立DB models
PictureCategory
using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace DennisEFDemo.CodeFirstDemo.DBModels { [Table("PictureCategory", Schema = "dbo")] public class PictureCategory { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int CategoryId { get; private set; } public string Name { get; set; } public int? ParentCategoryId { get; private set; } [ForeignKey("ParentCategoryId")] public virtual PictureCategory ParentCategory { get; set; } //書中沒有virtual關鍵字,這會導致導航屬性不能載入,後面的輸出就只有根目錄!! public virtual List<PictureCategory> Subcategories { get; set; } public PictureCategory() { Subcategories = new List<PictureCategory>(); } } }
- 在main函式中寫一個靜態方法
class Program { static void Main(string[] args) { RunExample(); Console.ReadKey(); } static void RunExample() { using (var context = new Ef6RecipesContext()) { var louvre = new PictureCategory { Name = "Louvre" }; var child = new PictureCategory { Name = "Egyptian ANTIQUITéS" }; louvre.Subcategories.Add(child); child = new PictureCategory { Name = "Sculptures" }; louvre.Subcategories.Add(child); child = new PictureCategory { Name = "Paintings" }; louvre.Subcategories.Add(child); var paris = new PictureCategory { Name = "Paris" }; paris.Subcategories.Add(louvre); var vacation = new PictureCategory { Name = "Summer Vacation" }; vacation.Subcategories.Add(paris); context.PictureCategories.Add(paris); context.SaveChanges(); } using (var context = new Ef6RecipesContext()) { var roots = context.PictureCategories.Where(c => c.ParentCategory == null); roots.ToList().ForEach(root => Print(root, 0)); } } static void Print(PictureCategory cat, int level) { StringBuilder sb = new StringBuilder(); Console.WriteLine("{0}{1}", sb.Append(' ', level).ToString(), cat.Name); cat.Subcategories.ForEach(child => Print(child, level + 1)); } }
- 修改app.config檔案(如果是web工程則為web.config)
<connectionStrings>
<add name="EF6CodeFirstRecipesContext" connectionString="Data Source=stcav-235\stcav235;initial catalog=EF6Recipes;user id=sa;password=`*******`;" providerName="System.Data.SqlClient" />
</connectionStrings>
- 執行程式,會在資料庫中建立相應的table並將資料寫入後讀取輸出到控制檯.
原始碼我會上傳到git上,連結稍後奉上.
DBModelBuilder
上述程式碼中的
Ef6RecipesContext
類中有個DBModelBuilder
,我查了一下文件, 一般使用這個類的EF專案基本上都是CODE FIRST approach.解釋一下這玩意:DbModelBuilder用於將CLR類對映到資料庫模型.
這種以程式碼為中心的構建實體資料模型(EDM)模型的方法稱為“程式碼優先(code first)”
DbModelBuilder通常用於通過重寫DbContext.OnModelCreating(DbModelBuilder)
來配置模型
還可以獨立於DbContext使用DbModelBuilder來構建模型
但是,推薦的方法是在DbContext中使用OnModelCreating, 優點是工作流程更直觀,可以處理常見任務,例如快取建立的模型。形成模型的型別在DbModelBuilder中註冊,可選配置,可以通過將資料註釋應用於您的類和使用流暢的樣式DbModelBuilder來執行API。
目前先寫到這兒,上述內容有誤還請點選下方圖示聯絡我, 如有新內容會繼續對此文進行更新,有興趣的話可以保持關注.