我的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).
他說沒有在程序集中發現遷移配置類型,可以使用enable-migrations添加配置
就是說要用這個遷移,要先執行 enable-migrations 命令來開啟一下遷移,這些命令不區分大小寫
我執行了命令:enable-migrations 發現我的項目中被創建了一個Migrations文件夾,里面有兩個文件
但是我並沒有看到剛剛添加的那個Test屬性,先不管,我們直接更新看看
輸入命令:update-database
然后他說沒有掛起的顯示遷移,什么意思,不就是說沒什么可以更新的嗎?
然后我再次生成一個新的遷移類文件,輸入命令:add-magration jinshantest 這個jinshantest就是你為這個遷移文件取的一個名字
現在就有了。
那么現在就更新到數據庫里面吧,現在我們再來執行遷移:update-database -verbose 加上-verbose就是顯示遷移的詳細信息
可以看到它根據遷移文件的內容,生成了創建列的SQL語句,並更新到了數據庫
改動了模型就要做數據遷移,繼續add-migration jinshantest2 生成遷移文件
可以的,他生成的SQL語句是下面這樣的。
ALTER TABLE [dbo].[Blogs] ADD [Test2] [nvarchar](max) NOT NULL DEFAULT ''

然后修改我們的Dbcontext文件,告訴EF我們的數據庫連接字符串
於是我運行程序,報錯了:找不到對象“dbo.Blogs”
我檢查我的的SQL server 里面什么都沒有。
難道是因為我Main方法里有做數據持久化的代碼,他在插入數據的時候找不到表,就報錯了?
剛剛在localDB里面不是好好的嗎?在對localDB操作的時候,我什么都沒做,他自動給我創建數據庫,創建表
難道我現在還要在SQL server中創建一個數據庫然后創建一個表?那要你做什么?
行,我弄了下,大概知道了,我要先做數據遷移才行,就是把剛剛的那些遷移文件現在針對我的SQL server執行,於是命令行輸入:update-database -verbose
行了,數據庫和表都有了。
SQLserver 和localDB就是這一點區別,localDB不用先遷移。
后面還有其他的很多配置,不過總算是能夠簡單地創建數據庫和表了,並且修改model后,我們利用數據遷移對數據庫做更新,還是比較完整吧。
書中的內容都是一點點講起的,數據遷移在后面才會講到。書有目錄啊,必須跟着目錄走啊。我自己隨便弄,還是覺得要用一個完整的東西把這些散碎的東西串起來好一些。