EF6學習筆記一:code-first簡單建立資料庫、表的一些過程
我的EF學習筆記是按照 汪鵬(網名Jeffcky) 大俠《你必須掌握的Entity Framework 6.x與Core 2.0》來弄的。
這也是我第一篇部落格,感覺這東西不能亂寫啊,算了,幹吧。
EF我之前是做過的,但是隻是一些零碎的東西,不成系統。
EF是什麼呢?ORM框架object renational mapping 物件關係對映,下面我就用自己的話來了。
資料庫裡面存放資料用表,而我們程式程式碼使用類,一個是資料世界的弄法,一個是物件世界的弄法。EF就是為我們做這種物件對映的處理,讓我可以不用關心資料庫,只關係類 怎麼設計就行了。
我說完了。它主要就是這個對吧,當然會有其他的很多東西,通過程式直接建立資料庫,然後更多的精力放到了類上,業務邏輯上,突然多出來的精力沒處使,是不是就弄出了什麼領域驅動設計?
現在來建立一個控制檯程式,安裝EF,開啟程式包管理控制檯輸入命令:install-package entityframework
建立Blog類,寫一個EFDbContext類,這個類派生自DbContext,為blog公開一個DbSet屬性
然後在main方法裡面例項化上下文物件,新增一個blog例項,接著查詢這個例項,打印出來
然後控制檯大概過了十多秒,看到了剛剛新增的資料,那麼簡單的建立資料庫、表就完了~
namespace _20190105 { public class Blog { public int ID { get; set; } public string Name { get; set; } public string Url { get; set; } public DateTime? CreatedTime { get; set; } public double Double { get; set; } public float Float { get; set; } } }
namespace _20190105 { // 此上下文是與資料庫互動的一箇中間橋樑,可以稱之為會話,為每一個模型公開一個DbSet<>,定義DbSet有三種方式 public class EFDbContext:DbContext { // DbSet 三種設計方式,不太懂,我隨便弄了一種 //public DbSet<Blog> Blog { get; set; } //public IDbSet<Blog> Blog { get; set; } public DbSet<Blog> Blog { get { return Set<Blog>(); } } } }
namespace _20190105 { class Program { static void Main(string[] args) { // 上下文例項化,新增一個blog例項 using (EFDbContext db = new EFDbContext()) { db.Blog.Add(new Blog { CreatedTime = DateTime.Now, Double = 11.11, Float = 2.2f, ID = 1, Name = "第er篇部落格", Url = "http://localhost:8080" }); db.SaveChanges(); Console.WriteLine(JsonConvert.SerializeObject(db.Blog.ToList())); } } } }
來看看資料庫,對照著模型看一下,資料庫和表是什麼樣子的。這裡要注意一點,如果是按照上面的幾步操作,EF預設會給我們把資料庫建立到localdb裡面
localdb是個什麼玩意,他也是個資料庫,但是這和我們SQL server資料庫管理工具建立的資料庫有什麼不一樣呢?網上說這個localdb完全是為了針對開發人員使用的,一個數據庫最大容量為10G,那他到底是在安裝VS的時候安裝的,還是在裝SQLserver安裝的呢?
要檢視剛剛建立的資料庫,在VS上點選“檢視”-->"SQL server資料庫物件資源管理器",也可以通過SQL server去連線它
通過SQL server管理工具連線到這個localdb,有可能你的機器上沒有安裝這個localdb,我這個沒有刻意去安裝,反正就是有這個東西
首先,資料庫建立在localdb裡面,資料庫的名稱是我們專案名稱空間+上下文類名
然後我們看錶名,我們的DbSet<>屬性是Blog,但是在資料庫裡面表明成了Blogs,變成複數形式了
然後我們看欄位,ID預設給我弄成了主鍵,並且設定為自增長
string型別對應nvarchar(max),並且允許為空
double型別對應float
float型別對應real
datetime?可空型別對應datetime,可空
剛剛我新增一個條資料,ID為1,現在我又新增一個blog例項,ID還是1,但是沒有報錯,正確插入進去了,ID自增長為2
然後我在Blog中新增一個欄位Test,再次執行,報錯
未經處理的異常: System.InvalidOperationException: The model backing the 'EFDbContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).
他說模型放生了改變,讓我用codefirst 遷移來更新資料庫 行,然後我在程式包管理器控制檯輸入 add-migration jinshantest,報錯 No migrations configuration type was found in the assembly '20190105'. (In Visual Studio you can use the Enable-Migrations command from Package Manager Console to add a migrations configuration).他說沒有在程式集中發現遷移配置型別,可以使用enable-migrations新增配置
就是說要用這個遷移,要先執行 enable-migrations 命令來開啟一下遷移,這些命令不區分大小寫
我執行了命令:enable-migrations 發現我的專案中被建立了一個Migrations資料夾,裡面有兩個檔案
但是我並沒有看到剛剛新增的那個Test屬性,先不管,我們直接更新看看
輸入命令:update-database
然後他說沒有掛起的顯示遷移,什麼意思,不就是說沒什麼可以更新的嗎?
然後我再次生成一個新的遷移類檔案,輸入命令:add-magration jinshantest 這個jinshantest就是你為這個遷移檔案取的一個名字
現在就有了。
那麼現在就更新到資料庫裡面吧,現在我們再來執行遷移:update-database -verbose 加上-verbose就是顯示遷移的詳細資訊
可以看到它根據遷移檔案的內容,生成了建立列的SQL語句,並更新到了資料庫
我現在又想到,我再新增一個欄位“Test2”並且設定為非空,看看它能不能給我更新到資料庫,更新之後是什麼樣子,這需求很正常吧
改動了模型就要做資料遷移,繼續add-migration jinshantest2 生成遷移檔案
可以的,他生成的SQL語句是下面這樣的。
ALTER TABLE [dbo].[Blogs] ADD [Test2] [nvarchar](max) NOT NULL DEFAULT ''
現在我想要EF面向我的SQL server 而不是localDB 那麼我需要在app.config檔案中加上資料庫連線字串的配置,他要其他的我也不會去配,因為Code-first不就是不用到處配東西,直接寫程式碼就行嗎? Initial Catlog=TestDB,這個TestDB在我資料庫裡面不存在,我當然不會弄一個已存在的資料庫,我的目的就是要讓它給我建立資料庫
然後修改我們的Dbcontext檔案,告訴EF我們的資料庫連線字串
於是我執行程式,報錯了:找不到物件“dbo.Blogs”
我檢查我的的SQL server 裡面什麼都沒有。
難道是因為我Main方法裡有做資料持久化的程式碼,他在插入資料的時候找不到表,就報錯了?
剛剛在localDB裡面不是好好的嗎?在對localDB操作的時候,我什麼都沒做,他自動給我建立資料庫,建立表
難道我現在還要在SQL server中建立一個數據庫然後建立一個表?那要你做什麼?
行,我弄了下,大概知道了,我要先做資料遷移才行,就是把剛剛的那些遷移檔案現在針對我的SQL server執行,於是命令列輸入:update-database -verbose
行了,資料庫和表都有了。
SQLserver 和localDB就是這一點區別,localDB不用先遷移。
後面還有其他的很多配置,不過總算是能夠簡單地建立資料庫和表了,並且修改model後,我們利用資料遷移對資料庫做更新,還是比較完整吧。
書中的內容都是一點點講起的,資料遷移在後面才會講到。書有目錄啊,必須跟著目錄走啊。我自己隨便弄,還是覺得要用一個完整的東西把這些散碎的東西串起來好一些。