<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
Data-Seeding是EntityFrameworkCore 2.1以上版本新增加的特性。在專案剛開始的時候,我們往往是需要初始化一些基礎資料到資料庫中,通過Data-Seeding特性就可以實現這一功能。本篇文章我們將講解如何進行資料初始化。
具體的資料初始化方法分為如下三種:
下面我們分別來講解如何使用這三種方式進行資料遷移。
這種方式是通過呼叫HasData()方法實現的。這種也是我在專案開發過程中,經常使用的。這種方式是在資料上下文類中重寫OnModelCreating()方法,我們先看HasData()方法的定義:
可以看到,方法的引數可以是Blog型別的陣列,具體程式碼如下:
using EFCore.Model; using Microsoft.EntityFrameworkCore; namespace EFCore.Data { /// <summary> /// 資料上下文 /// </summary> public class EFDbContext:DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer("Data Source=.;Initial Catalog=EFTest;User ID=sa;Password=123456;"); } public DbSet<Blog> Blogs { get; set; } /// <summary> /// 重寫OnModelCreating方法 /// </summary> /// <param name="modelBuilder"></param> protected override void OnModelCreating(ModelBuilder modelBuilder) { // 針對Blog實體新增種子資料 modelBuilder.Entity<Blog>().HasData( new Blog() { // Id欄位要賦值,否則會報錯 Id=1, Name="ef core" }, new Blog() { Id=2, Name="ASP.NET Core" }, new Blog() { Id=3, Name="圖解資料結構" } ); base.OnModelCreating(modelBuilder); } } }
我們注意到:預設情況下會自動設定Id列為主鍵,並且是自動增長的。但是這裡要設定Id的值,即使Id是自動生成的主鍵,否則會報下圖所示的錯誤:
新增完種子資料以後,我們執行程式,檢視輸出結果:
檢視資料庫:
這樣就生成了資料庫和表,而且表裡面也有了初始化資料。
假如這時候我們想增加一條資料,程式碼如下:
using EFCore.Model; using Microsoft.EntityFrameworkCore; namespace EFCore.Data { /// <summary> /// 資料上下文 /// </summary> public class EFDbContext:DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer("Data Source=.;Initial Catalog=EFTest;User ID=sa;Password=123456;"); } public DbSet<Blog> Blogs { get; set; } /// <summary> /// 重寫OnModelCreating方法 /// </summary> /// <param name="modelBuilder"></param> protected override void OnModelCreating(ModelBuilder modelBuilder) { // 針對Blog實體新增種子資料 modelBuilder.Entity<Blog>().HasData( new Blog() { // Id欄位要賦值,否則會報錯 Id=1, Name="ef core" }, new Blog() { Id=2, Name="ASP.NET Core" }, new Blog() { Id=3, Name="圖解資料結構" }, // 新增加一條資料 new Blog() { Id=4, Name="C#高階程式設計" } ); base.OnModelCreating(modelBuilder); } } }
這時候還能不能用剛才的方法呢?我們這時在執行程式,檢視結果:
這時候程式執行失敗了,而且表裡面的資料也沒有增加。這說明context.Database.EnsureCreated()方法只有在第一次執行的時候才會有效,以後資料進行更改後就無效了。那麼有什麼方式可以實現呢?這時只有通過命令列進行遷移或者通過context.Database.Migrate方法呼叫生成的遷移類才能對資料的更改有效。
我們把剛才生成的資料庫刪掉,新增加的那條資料註釋掉,然後使用命令列遷移的方式生成資料庫表,首先新增遷移:
然後更新資料庫:
更新完資料庫以後,我們在HasData()方法裡面新增一條資料,然後再次執行上面的新增遷移和更新資料庫的命令,發現這時候資料庫裡面會新增新增加的資料。
在執行完第二次新增遷移命令後,如果不使用更新資料庫命令,也可以通過程式碼的方式進行遷移,這就是呼叫context.Database.Migrate命令,程式碼如下:
using EFCore.Data; using Microsoft.EntityFrameworkCore; using System; namespace EFCore.Con { class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); EFDbContext dbContext = new EFDbContext(); // 遷移 dbContext.Database.Migrate(); //bool tfTrue = dbContext.Database.EnsureCreated(); //if(tfTrue) //{ // Console.WriteLine("資料庫建立成功!"); //} //else //{ // Console.WriteLine("資料庫建立失敗!"); //} Console.ReadKey(); } } }
這時會自動呼叫最新的遷移檔案去更新資料庫。
注意:呼叫該方法對資料的更改只有在遷移時才能生效,也就是說只有通過命令進行遷移或者通過context.Database.Migrate方法呼叫生成的遷移類才能對資料更改有效。而呼叫context.Database.EnsureCreated()方法只有在第一次執行的時候才有效,但資料進行更改後將無效。
這種方式有兩種限制:
這種方式在這裡不進行講解,有興趣的可以參考微軟的官方檔案。
執行資料種子設定的一種簡單而有效的方法是在主應用程式邏輯開始執行之前使用使用DbContext.SaveChanges()。程式碼如下:
using EFCore.Data; using EFCore.Model; using Microsoft.EntityFrameworkCore; using System; using System.Linq; namespace EFCore.Con { class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); //EFDbContext dbContext = new EFDbContext(); //// 遷移 //dbContext.Database.Migrate(); ////bool tfTrue = dbContext.Database.EnsureCreated(); ////if(tfTrue) ////{ //// Console.WriteLine("資料庫建立成功!"); ////} ////else ////{ //// Console.WriteLine("資料庫建立失敗!"); ////} #region 使用自定義初始化邏輯 using(EFDbContext context=new EFDbContext()) { context.Database.EnsureCreated(); var testBlog = context.Blogs.FirstOrDefault(p => p.Name == "C#"); if(testBlog == null) { // 新增資料 context.Blogs.Add(new Blog() { Name = "C#" }); } // 儲存資料 context.SaveChanges(); } #endregion Console.ReadKey(); } } }
通過這種自定義邏輯的方式也可以新增種子資料。如果HasData()方法裡面新增了種子資料,那麼會先把HasData()方法裡面的種子資料新增到資料庫中。如果沒有名稱為C#的資料,則還會在新增一條資料。
如果有了該資料,就不會再新增了。
注意:這種方式新增資料的時候就不能再給主鍵Id賦值了,因為是先生成資料庫,自動設定Id為主鍵,在新增資料的時候會自動賦值。
我們在第一次執行完新增遷移命令以後,會生成一個遷移檔案,如下圖所示:
可以看到這時就是呼叫的InsertData方法來新增資料。
我們修改資料,將ef core修改為ef core 3.1.1,如下圖所示:
修改完以後我們在執行遷移命令,如圖所示:
這時在去看生成的遷移檔案:
這時執行的就是UpdateData方法。
接著我們把Id為1的資料在程式碼裡面註釋掉模擬刪除操作,在執行遷移命令:
在看生成的遷移檔案:
可以看到這次就是執行的DeleteData方法。
我們在把Id為2的資料修改為6:
在執行遷移:
檢視生成的遷移檔案:
這次就是先執行DeleteData方法,然後在執行InsertData方法。
針對種子資料初始化,主要有上面的三種方式,比較推薦的是第一種和第三種,可以根據自己的使用情況來選擇適合自己的。
到此這篇關於Entity Framework Core種子資料Data-Seeding的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45