## 前言 這邊文章紀錄使用 .net core 7 MVC 連線到mysql資料庫,進行基本CRUD的操作 以下是完成後的結果 ![image](https://hackmd.io/_uploads/S1OXLArq6.png) 接下來將以資料庫建立、 註冊服務 、 DbContext 、appsettings.json、API Controller 的實作進行說明 ## 資料庫建立 先透過mysqlworkbench在本地端建立 ``` sql= create database TestConn; use TestConn; create table Connection(ConnectionId INT AUTO_INCREMENT PRIMARY KEY, ConnStr varchar(100), Remark varchar(100)); insert Connection(Connstr, remark) values('conn1', 'remark1'); insert Connection(Connstr, remark) values('conn2', 'remark2'); insert Connection(Connstr, remark) values('conn3', 'remark3'); ``` ![image](https://hackmd.io/_uploads/Hy3iwABqa.png) ## DbContext & Model 建立Connection類別 ```csharp= public class Connection { [Key] public int ConnectionId { get; set; } public string ConnStr { get; set; } public string Remark { get; set; } } ``` 建立 DbContext ```csharp= public class TestConnDBContext : DbContext { public DbSet<Connection> Connection { get; set; } public TestConnDBContext(DbContextOptions<TestConnDBContext> options) : base(options) { } } ``` ### DbContext介紹 `DbContext` 是 Entity Framework (EF) 中的一個基本類別,它代表了與資料庫的一次會話,並允許您對資料庫進行 CRUD(創建、讀取、更新、刪除)操作。在使用 Entity Framework 進行 .NET 應用程序開發時,您會操作 DbContext 類別的實例來與資料庫互動。 以下是 `DbContext` 的一些主要功能: 1. **查詢:** 使用 LINQ(Language Integrated Query)語言,可以寫出類似於 SQL 的查詢來從資料庫檢索資料。Entity Framework 會將這些 LINQ 查詢轉換成適合資料庫的 SQL 查詢。 2. **保存變更:** 在內存中對實體進行增刪改操作後,可以通過 `DbContext` 提供的 `SaveChanges()` 方法把這些變更保存到資料庫中。這個過程包括生成對應的 SQL 命令並執行它們。 3. **跟蹤變更:** `DbContext` 會自動跟蹤實體的變更狀態,當您對實體進行操作時,它會知道實體是被新增、修改還是刪除了。當調用 `SaveChanges()` 方法時,`DbContext` 會根據實體的狀態生成相應的 SQL 語句。 4. **緩存:** 第一次查詢數據時,`DbContext` 會將數據放入內存緩存中。如果相同的數據再次被查詢,它會從緩存中取出來,而不是從資料庫。這可以提高應用程序的性能。 5. **管理關聯性:** `DbContext` 能夠管理資料庫表之間的關聯(如一對多、多對多等),並能夠方便地表示和操縱這些關聯。 ## 註冊服務 在program.cs 中註冊`DbContext` ```csharp= // Add DbContext with MySQL services.AddDbContext<TestConnDBContext>(options => options.UseMySql(configuration.GetConnectionString("DefaultConnection"), ServerVersion.AutoDetect(configuration.GetConnectionString("DefaultConnection")))); ``` ### 說明 這段程式碼在ASP.NET Core的依賴注入(DI)系統中註冊TestConnDB這個DbContext。 具體來說,它做了以下幾點: * **依賴注入註冊**: AddDbContext是一個擴充方法,用於將TestConnDB DbContext類別註冊為服務。 這樣,在控制器或其他服務中需要存取資料庫時,TestConnDB實例可以透過建構函式註入自動提供。 * **設定資料庫提供者**: 使用options.UseMySql指定Entity Framework Core使用MySQL作為資料庫提供者。 這裡告訴EF Core用於應用程式的資料庫是MySQL。 * **設定資料庫連線字串**: 透過builder.Configuration.GetConnectionString("DefaultConnection")從設定(通常是appsettings.json檔案或環境變數)取得名為"DefaultConnection"的資料庫連線字串。 * **自動偵測伺服器版本**: ServerVersion.AutoDetect用於自動偵測MySQL伺服器的版本。 這對於EF Core在產生SQL指令時考慮特定版本的資料庫特性和行為很重要。 ## appsettings.json 在appsettings.json檔案中,加入以下內容 ``` json= "ConnectionStrings": { "DefaultConnection": "Server=localhost;Database=TestConn;User Id=root;" } ``` ### 說明 這段 JSON 配置是定義在 ASP.NET Core 應用程式的 appsettings.json 檔案中,用於儲存資料庫連接字串的設定。 它是設定檔中的一部分,讓您可以在不修改程式碼的情況下,指定與資料庫連接有關的資訊。 以下是對這段配置的逐一解釋: * **"ConnectionStrings"**:這是一個 JSON 物件,包含應用程式中所有資料庫連接字串的設定。 您可以在這裡定義一個或多個連接字串。 * **"DefaultConnection"**:這是連接字串的名稱。 在代碼中,您會通過這個名稱來獲取連接字串的值。 這個名字是自訂的,您可以根據需要命名。 * **"Server=localhost;Database=TestConn;User Id=root;"**:這是一個特定的連接字串,用於定義如何連接到資料庫。 具體來說: * **Server=localhost**:指定資料庫伺服器的位置。 在這個例子中,它指向本機(localhost),通常用於開發環境。 * **Database=TestConn**:指定要連線的資料庫的名稱。 在這個例子中,資料庫名為 TestConn。 * **User Id=root**:指定用於連接資料庫的使用者名稱。 這裡使用的是 root,通常是MySQL資料庫的預設管理員帳號。 在您的應用程式中,當 Entity Framework Core 或其他資料庫用戶端程式庫嘗試建立資料庫連線時,它們會使用這個連接字串中定義的參數。 您可以透過 configuration.GetConnectionString("DefaultConnection") 這樣的程式碼來取得這個連接字串,並在您的應用程式中使用它,正如之前在 DbContext 的配置中所做的那樣。 ## API Controller ```csharp= using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using StockBacktesting.Models; namespace StockBacktesting.Controllers { [ApiController] [Route("[controller]")] public class ItemsController : ControllerBase { private readonly TestConnDBContext _context; public ItemsController(TestConnDBContext context) { _context = context; } // 获取所有项目 [HttpGet] public ActionResult<List<Connection>> GetAll() => _context.Connection.ToList(); // 通过ID获取项目 [HttpGet("{id}")] public ActionResult<Connection> GetById(int id) { var item = _context.Connection.Find(id); if (item == null) { return NotFound(); } return item; } // 创建新项目 [HttpPost] public ActionResult<Connection> Create(Connection connection) { _context.Connection.Add(connection); _context.SaveChanges(); return CreatedAtAction(nameof(GetById), new { id = connection.ConnectionId }, connection); } // 更新项目 [HttpPut("{id}")] public IActionResult Update(int id, Connection connection) { if (id != connection.ConnectionId) { return BadRequest(); } _context.Entry(connection).State = EntityState.Modified; try { _context.SaveChanges(); } catch (DbUpdateConcurrencyException) { if (!_context.Connection.Any(e => e.ConnectionId == id)) { return NotFound(); } else { throw; } } return NoContent(); } // 删除项目 [HttpDelete("{id}")] public IActionResult Delete(int id) { var connection = _context.Connection.Find(id); if (connection == null) { return NotFound(); } _context.Connection.Remove(connection); _context.SaveChanges(); return NoContent(); } } } ```