1. 程式人生 > 其它 >Entity Framework Core 筆記 - 入門

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         public
int 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         }

以上程式碼執行了增刪改查所有操作,操作結果如下: