Entity Framework Core 筆記 - 入門
先決條件
請確保安裝了 .NET Core 第6 或 7 版本,我這安裝的是 7.
一. 領域建模方式
1. Code First
POCO:Plain Old CLR Object。內在含義是指那些沒有從任何類繼承、也沒有實現任何介面,更沒有被其它框架侵入的物件。
EF 4.0 之前的物件需要從 EntityObject 基類繼承,4.0 開始引入了 POCO 資料模型。POCO 要儘可能簡單,可以包含屬性和方法,但方法不能實現持久化邏輯。
使用 Code First 模型可以完全以面向物件的方式工作。這是最受歡迎的領域建模方式,沒有自動生成的難以管理的程式碼,只需要定義對映,別的交給 EF 處理。
2. Model First
使用實體設計器在 .edmx 中建立模型實體及其關係和繼承層次結構,然後建立資料庫。
優點是視覺化,缺點是無法控制程式碼和資料庫,因為程式碼是自動生成的,如果在 POCO 中添加了自定義的程式碼,模型變動後自動生成會覆蓋掉程式碼修改,解決辦法是得使用 T4 模板(不太瞭解)或者使用部分類。
3. Database First
如果有現有資料庫,或者 DBA 設計好了資料庫,那麼可以使用這種方式。
缺點是程式碼是自動生成的,這個和第二種方式一樣的。
二. 安裝 EF
在 VS2022 中新建一個控制檯程式,然後右鍵專案,選擇“管理 NUGet 程式包”。
在 Nuget 管理頁面填寫“Entity Framework”並搜尋,因為我使用的資料庫是 SQL Server,因此這裡選擇“Microsoft.EntityFrameworkCore.SqlServer”,下載這個包時會下載相應的依賴。
這樣就不用糾結搜尋出來這麼多選項需要安裝哪些了,安裝後可以檢視相關依賴。可以參見:https://learn.microsoft.com/zh-cn/ef/core/get-started/overview/install。
三. 模型
對於 EF Core,使用模型執行資料訪問。 模型由實體類和表示資料庫會話的上下文物件構成。
1 public class Blog 2 { 3 public int BlogId { get; set; } 4 5 public string Url { get; set; } 6 7 publicint Rating { get; set; } 8 9 public List<Post> Posts { get; set; } 10 11 public string toString() 12 { 13 return $"BlogId: {this.BlogId}, Url: {this.Url}"; 14 } 15 }
1 public class Post 2 { 3 public int PostId { get; set; } 4 5 public string Title { get; set; } 6 7 public string Content { get; set; } 8 9 10 public int BlogId { get; set; } 11 12 public Blog Blog { get; set; } 13 }
資料庫上下文型別。
1 public class BloggingContext : DbContext 2 { 3 public DbSet<Blog> Blogs { get; set; } 4 5 public DbSet<Post> Posts { get; set; } 6 7 8 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 9 { 10 optionsBuilder.UseSqlServer( 11 @"Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True"); 12 } 13 }
四. 建立資料庫
我們上面建立了模型,接下來使用遷移來建立資料庫。這裡需要藉助一些工具,有關的兩個工具集如下:
1).NET Core 命令列介面 (CLI) 工具可用於 Windows、Linux 或 macOS。 這些命令以 dotnet ef 開頭。
將 dotnet ef 安裝為全域性工具或本地工具。 大多數開發人員偏向於使用以下命令將 dotnet ef 安裝為全域性工具:
dotnet tool install --global dotnet-ef
更新工具使用以下命令:dotnet tool update
2)包管理器控制檯 (PMC) 工具在 Windows 上的 Visual Studio 中執行。 這些命令以動詞開頭,例如 Add-Migration、Update-Database。
獲取適用於 EF Core 的包管理器控制檯工具,需要安裝 Microsoft.EntityFrameworkCore.Tools 包。
Install-Package Microsoft.EntityFrameworkCore.Tools
完整的遷移命令過程如下:
1)安裝 dotnet ef,上面已提及。
dotnet tool install --global dotnet-ef
2)安裝命令列 EF Core 開發的工具套件。
dotnet add package Microsoft.EntityFrameworkCore.Design
這個命令需要在專案檔案內執行,否則會報錯。
3)這個我暫時沒查到作用是什麼。。同樣需要在專案檔案內執行。
dotnet ef migrations add InitialCreate
4)遷移。
dotnet ef database update
執行報了一個錯誤,“證書鏈是由不受信任的頒發機構頒發的”。
查詢了錯誤,發現是和客戶端驅動程序升級後預設行為的改變有關(https://learn.microsoft.com/zh-cn/troubleshoot/sql/connect/certificate-chain-not-trusted?tabs=ole-db-driver-19)。
如果最近將 SQL Server Native Client 11.0 (Provider=SQLNCLI11) 應用程序升級為使用 Microsoft OLE DB Driver 19 for SQL Server (Provider=MSOLEDBSQL19) ,則可能會收到類似於以下
訊息的錯誤訊息: [Microsoft OLE DB Driver 19 for SQL Server]:客戶端無法建立連線 [Microsoft OLE DB Driver 19 for SQL Server]:SSL 提供程式:證書鏈由不受信任的頒發機構頒發。 原因 如果這兩個條件都為 true,則會發生這些錯誤: 1. SQL Server例項的 Force 加密設定設定為“否”。 2. 客戶端連線字串未顯式指定加密屬性的值,或者未在 DSN 中顯式設定或更新 加密 選項。 由於客戶端驅動程式的預設行為發生更改,因此會發生錯誤。 舊版客戶端驅動程式旨在假定預設情況下資料加密為 OFF 。 預設情況下,新驅動程式假定此設定為 ON 。 由於資料加密設定為 ON,因此驅動程式嘗試驗
證伺服器的證書並失敗。
解決方案給出了 3 種。
解決方案 1:使用 Microsoft OLE DB Driver for SQL Server 18.x。 可以從Microsoft OLE DB Driver for SQL Server的發行說明下載驅動程式。 解決方案 2:如果應用程式連線字串屬性已指定用於資料設定的加密/使用加密的“是”或“必需”值,請將值更改為“否”或“可選”。 例如, 對 Data=Optional 使用加密。 如果連線字串未為 “加密”/“使用資料加
密”指定任何值,請向連線字串新增 “Data 的使用加密”=“可選 ”。 有關詳細資訊,請參閱加密 和證書驗證。 解決方案 3: 新增 ;Trust Server Certificate=true 到連線字串。 這將強制客戶端在不進行驗證的情況下信任證書。
我採用了最簡單的第 3 種,然後就成功了。
查詢資料庫,發現已經新建了資料庫和表。
五. 增刪改查
1 static void Main(string[] args) 2 { 3 using(var dbContext = new BloggingContext()) 4 { 5 var blogs = dbContext.Blogs; 6 7 Console.WriteLine("Inserting a new blog"); 8 dbContext.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/adonet" }); 9 dbContext.SaveChanges(); 10 Console.WriteLine("Inserting complete."); 11 Console.WriteLine(); 12 13 Console.WriteLine("Querying for a blog"); 14 var blog = dbContext.Blogs.OrderBy(b => b.BlogId).FirstOrDefault(); 15 Console.WriteLine(blog.toString()); 16 Console.WriteLine(); 17 18 Console.WriteLine("Updating the blog and adding a post"); 19 blog.Url = "https://devblogs.microsoft.com/dotnet"; 20 dbContext.SaveChanges(); 21 blog = dbContext.Blogs.OrderBy(b => b.BlogId).First(); 22 Console.WriteLine("Updating complete."); 23 Console.WriteLine(blog.toString()); 24 Console.WriteLine(); 25 26 27 Console.WriteLine("Delete the blog"); 28 dbContext.Remove(blog); 29 dbContext.SaveChanges(); 30 Console.WriteLine("Delete complete."); 31 } 32 }
以上程式碼執行了增刪改查所有操作,操作結果如下: