---
# System prepended metadata

title: .net core 7 如何連線到mysql 進行CRUD 操作

---


## 前言
這邊文章紀錄使用 .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();
        }
    }
}

```