接上一篇文章。現在寫程式,做專案不是說功能做完就完事了,在平常的開發過程中對於效能的考慮也是極其重要的。
關於ef的那些事,今天就來說說吧。首先必須得知道.net ef在程式中的五種狀態變化過程與原理。
主要來說說查詢部分的效能優化,在所有查詢中,客戶端查詢出來的資料一般來說是不需要進行跟蹤的。也就是說查詢只是給使用者看,不做其他任何操作。對於基於B/S模式的專案網站開發,應該是無狀態的,也就是ef中的遊離態(Unchanged)(個人理解)。如果是C/S可能還需要進行其他連線的狀態。通俗的說,在開發過程不用去檢測某一個屬性或者類是否被修改或者刪除。
例如:
AsNoTracking:它的作用就是在查詢的過程中不被快取,也就是不被保留,查出來就完事了,這樣的狀態就變成了Detached遊離態
//AsNoTracking:它的效能比ToList快大約4.8倍,不被快取的資料。 var item=db.Book.AsNoTracking().First(m=>m.Id==1); Console.WriteLine(db.Entry(item).State); //輸出Detached(遊離態)
去掉AsNoTracking
var item=db.Book.First(m=>m.Id==1); Console.WriteLine(db.Entry(item).State); //輸出UnChanged(持久態)
也就是加上AsNoTracking做出來的查詢操作,就和資料庫斷絕了關係(個人理解)這樣對效能也是一個極好的優化。
然後來說說在專案中對ef整體框架優化的使用。
C#是一門物件導向的語言無外乎就是封裝、繼承、多型。。。類可以繼承類,同樣介面也可以繼承介面。物件導向的思想就是每張表都應該有一個父類,只寫一遍,其他類繼承就好了不用重複去寫。
建立一個空白的解決方案,新增一個名為BaseEntity的類,你可以把它看做是所有類的基礎類(父類)。
重點來說說這個BaseEntity為什麼要作為基礎類,它的用意何在。
先看看裡面的寫了些什麼吧!
以前用int或者long作為主鍵自增長的資料型別,這樣後期資料非常龐大的時候可能會無法預估難免可能會出現重複的資料,這個時候對於整個系統來說就無法保障了。
Guid給我做出了一個計算,它是32位的數字加字母的組合,而且是特別長的不會重複的自增數,可以這樣去理解。
DateTime就是每條資料的建立時間,IsRemove就是作為資料邏輯刪除的標識,也就是說,每個類(表)都會存在這三個欄位屬性。你可以通過DateTime對沒張表進行排序的操作。
using System; namespace Book.Models { public class BaseEntity { public Guid Id { get; set; }=Guid.NewGuid(); //計算32位,字母加數字,特別長的,不重複的,自增數 public DateTime DateTime { get; set; }=DateTime.Now; //每條資料的建立時間 public bool IsRemove { get; set; } //偽刪除的標識 } }
建立BookType類
using System.ComponentModel.DataAnnotations; namespace Book.Models { public class BookType:BaseEntity { [StringLength(20)] public string Name { get; set; } } }
建立Book類
using System.ComponentModel.DataAnnotations; namespace Book.Models { public class Book:BaseEntity { [StringLength(50),Required] public string Name { get; set; } public decimal Price { get; set; } } }
這兩個類都會繼承BaseEntity
在App.Config裡面寫上你自己的資料庫連線字串
這樣的目的就是去生成資料庫,只做生成資料庫的操作。這裡只是在Models層寫了一次,在後期加上表示層還有在寫一遍!
接下來就是去通過指令遷移到資料庫,操作有三步:
- 啟動遷移:enable-migrations
- 新增遷移:add-migration '引數'
- 更新資料庫:update-database(如果你需要新增或者修改某個欄位屬性,只需要進行第二步和第三步的操作即可!)
記住預設專案要選擇你的Models,如果是多個專案(我這裡是只有一個)就必須要把Models設為啟動專案,不然遷移指令可能不會起到作用