博客 / 詳情

返回

筆記:如何使用 Entity Framework Core

前言

在本篇文章中,着重介紹如何使用 Entity Framework Core,不過多涉及底層細節。

Entity Framework Core(簡稱 EF Core)是微軟為.NET 平台打造的輕量級、跨平台對象關係映射(ORM)框架,以編寫 C# 對象代碼的方式操作各類數據庫,無需大量手寫原生 SQL 語句。

其中有兩大概念,也是本文要講述的內容:

  • DbContext 配置和初始化
  • 模型的創建與使用

DbContext

DbContext 是 EF Core 中連接 C# 代碼與數據庫的核心橋樑類(需要繼承 EF Core 的 DbContext 基類自定義),所有對數據庫的增刪改查操作,都必須通過它來完成。

它的核心作用可以概括為 3 點:

  1. 管理數據庫連接:自動處理和數據庫的連接建立、釋放,無需你手動寫連接代碼;
  2. 提供表操作入口:通過 DbSet<T> 屬性(比如 DbSet<User>)對應數據庫的一張表,是操作表的唯一入口;
  3. 翻譯與執行:把對 C# 實體類的 LINQ 操作(比如 Add 新增、Where 查詢)自動轉換成 SQL 語句,提交到數據庫執行。

DbSet<T> 是 EF Core 提供的泛型集合類型,泛型參數 T 必須是定義的實體類

模型

EF Core 裏的 “模型”,本質是程序中所有實體類、實體間關係,以及這些實體與數據庫表 / 字段映射規則的整體描述

它的核心作用可以概括為兩點:

  1. 是 EF Core 的認知基礎:EF Core 只有先通過模型知道 “User 類對應 Users 表、Id 屬性對應主鍵字段、一個用户對應多個商品”,才能正確把 C# 操作(比如新增用户)翻譯成對應的 SQL 語句;
  2. 代碼與數據庫的契約:不管是從代碼生成數據庫(Code First),還是從數據庫生成代碼(Database First),核心都是基於這個模型來對齊代碼和數據庫的結構。

DbContext 配置和初始化

配置

配置的核心目標是讓 EF Core 知道:要連接的數據庫地址 / 認證信息(連接字符串)、數據庫類型(SQL Server/MySQL/PostgreSQL 等)。有兩種常用配置方式,適配不同場景:

OnConfiguring 方法

這是最基礎的配置方式,直接在自定義 DbContext 中重寫 OnConfiguring 方法,手動指定連接字符串和數據庫提供器。

using Microsoft.EntityFrameworkCore;

// 自定義 DbContext
public class AppDbContext : DbContext
{
    // 定義 DbSet(對應數據庫表)
    public DbSet<User> Users { get; set; }

    // 核心配置:重寫 OnConfiguring 指定數據庫連接
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        // 1. 連接字符串,包含數據庫地址/認證信息
        string sqlServerConn = "Server=(localdb)\\mssqllocaldb;Database=MyDatabase;Trusted_Connection=True;";
        // PostgreSQL 連接字符串示例(需安裝 Npgsql.EntityFrameworkCore.PostgreSQL 包)
        // string pgsqlConn = @"Host=myserver;Username=mylogin;Password=mypass;Database=mydatabase";

        // 2. 指定數據庫提供器(告訴 EF Core 用哪種數據庫)
        optionsBuilder.UseSqlServer(sqlServerConn); // SQL Server
        // optionsBuilder.UseNpgsql(mySqlConn, ServerVersion.AutoDetect(pgsqlConn)); // PostgreSQL
    }
}

// 簡單實體類
public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}
  • DbContextOptionsBuilder:EF Core 的配置構建器,專門用來設置數據庫相關選項;
  • 數據庫提供器需安裝對應 NuGet 包(如 SQL Server 安裝 Microsoft.EntityFrameworkCore.SqlServer);
  • 鏈接不同的數據庫,需要使用 DbContextOptionsBuilder 不同的 ues* 方法,比如使用 SQLite 使用 UseSqlite、MySql 使用 UseMySql

依賴注入(DI)方法

將 DbContext 註冊到依賴注入容器,由容器統一管理配置和生命週期,避免硬編碼和手動管理資源。

  1. 自定義 DbContext(無需重寫 OnConfiguring
using Microsoft.EntityFrameworkCore;

public class AppDbContext : DbContext
{
    // 構造函數接收 DI 容器傳入的配置(核心)
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

    // 定義DbSet
    public DbSet<User> Users { get; set; }
}
  1. Program.cs 中註冊 DbContext(項目入口)
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

// 1. 設置數據庫連接字符串
string connStr = "Server=(localdb)\\mssqllocaldb;Database=MyDatabase;Trusted_Connection=True;";

// 2. 註冊 DbContext 到 DI 容器
builder.Services.AddDbContext<AppDbContext>(options =>
{
    options.UseSqlServer(connStr); // 指定數據庫提供器
});

var app = builder.Build();
app.Run();
  • AddDbContext:將 DbContext 註冊到 DI 容器,容器自動管理其創建 / 釋放;
  • 構造函數注入 DbContextOptions<AppDbContext>:接收容器的配置,無需手動寫 OnConfiguring

初始化

配置完成後,需創建 DbContext 實例才能操作數據庫,對應兩種配置方式有兩種初始化方式:

直接 new 實例(對應 OnConfiguring 配置)

手動創建實例,必須用 using 包裹,確保使用後釋放數據庫連接(避免連接泄露)。

// using語句:自動釋放 DbContext 資源(數據庫連接)
using (var dbContext = new AppDbContext())
{
    // 新增數據
    var newUser = new User { Name = "張三", Age = 25 };
    dbContext.Users.Add(newUser);
    dbContext.SaveChanges(); // 提交更改

    // 查詢數據
    var allUsers = dbContext.Users.ToList();
    Console.WriteLine($"共查詢到 {allUsers.Count} 個用户");
}

DI 注入實例(對應 DI 配置)

在控制器、服務類中通過構造函數接收 DbContext 實例,由 DI 容器自動創建和注入,無需手動管理生命週期。

// ASP.NET Core 控制器示例
[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
    // 私有字段存儲 DbContext 實例
    private readonly AppDbContext _dbContext;

    // 構造函數注入:DI 容器自動傳入 AppDbContext
    public UserController(AppDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    // 接口中使用 DbContext
    [HttpGet]
    public IActionResult GetAllUsers()
    {
        var users = _dbContext.Users.ToList();
        return Ok(users);
    }
}

模型創建

模型的核心是實體類(Entity),但不是隨便寫的類都能被 EF Core 識別 ——EF Core 遵循 “約定優於配置” 原則,只要實體類滿足基礎規則,DbContext 就能自動識別;若需自定義規則,也可通過註解 / Fluent API 補充配置。

基礎實體類定義(零配置)

只需遵循 EF Core 的默認約定,就能讓 DbContext 自動識別實體並映射為表:

  • 主鍵約定:屬性名為 Id 或 “實體名 + Id”(如 UserId),EF Core 自動識別為主鍵;int/long 類型主鍵默認自增。
  • 字段映射:C# 基礎類型(string/int/decimal 等)自動映射為數據庫對應類型。
  • 關係約定:通過 “導航屬性”(如 User 中的 List<Order>)自動識別實體間的一對多 / 多對一關係。
// 示例1:用户實體(默認映射到 Users 表)
public class User
{
    // 主鍵:EF Core 自動識別 Id 為主鍵,int 類型默認自增
    public int Id { get; set; }
    // 普通字段:string → 數據庫 nvarchar(MAX)(默認, SQL Server 的類型)
    public string UserName { get; set; }
    // 普通字段:int→數據庫int
    public int Age { get; set; }
    // 導航屬性:一對多關係,指向 Order(不生成實際列,僅用於識別關係)
    public List<Order> Orders { get; set; } = new List<Order>(); // 初始化避免空引用
}

// 示例2:訂單實體(默認映射到Orders表)
public class Order
{
    public int Id { get; set; }
    public string OrderTitle { get; set; }
    public decimal Amount { get; set; }
    // 外鍵約定:“關聯實體名+Id”(UserId)自動識別為外鍵,關聯 User 的 Id
    public int UserId { get; set; }
    // 反向導航屬性:確認訂單歸屬的用户
    public User User { get; set; }
}

可選:自定義模型配置

若默認規則不滿足需求(如自定義表名、字段長度、主鍵不自增),可通過兩種方式配置:

  • 數據註解(Attribute):直接標註在實體 / 屬性上,簡單直觀;
  • Fluent API:在 DbContext 的 OnModelCreating 中配置,功能更強大,推薦複雜場景。
// 數據註解示例:自定義User實體規則
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

[Table("Sys_User")] // 自定義表名(不再默認是Users)
public class User
{
    [Key] // 顯式標記主鍵(可選,默認Id已識別)
    [DatabaseGenerated(DatabaseGeneratedOption.None)] // 主鍵不自增
    public int Id { get; set; }

    [Column("UserName", TypeName = "nvarchar(50)")] // 自定義列名+長度
    [Required] // 非空約束
    public string UserName { get; set; }

    [Range(0, 120)] // 數值範圍約束
    public int Age { get; set; }

    public List<Order> Orders { get; set; } = new List<Order>();
}

DbContext 如何自動識別模型

DbContext 是識別模型的核心,它通過 “顯性聲明 + 隱性發現” 的方式,把分散的實體類整合為完整的 “模型元數據”(EF Core 認知數據庫結構的依據),過程分 3 步:

第一步:顯性聲明:通過 DbSet<T> “註冊” 實體

在自定義 DbContext 中聲明的 DbSet<T> 屬性,是 DbContext 識別模型的核心入口,相當於明確告訴 DbContext:“這些實體需要映射到數據庫表”。

using Microsoft.EntityFrameworkCore;

public class AppDbContext : DbContext
{
    // 顯性聲明:告訴 DbContext 要處理 User 和 Order 實體
    public DbSet<User> Users { get; set; }
    public DbSet<Order> Orders { get; set; }

    // 配置數據庫連接
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        string connStr = "Server=(localdb)\\mssqllocaldb;Database=MyDatabase;Trusted_Connection=True;";
        optionsBuilder.UseSqlServer(connStr);
    }

    // 第二步:Fluent API 補充配置(可選,覆蓋/補充默認規則)
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // 自定義Order的OrderTitle字段:長度100+非空
        modelBuilder.Entity<Order>()
            .Property(o => o.OrderTitle)
            .HasMaxLength(100)
            .IsRequired();

        // 顯式配置一對多關係(可選,默認已識別)
        modelBuilder.Entity<Order>()
            .HasOne(o => o.User) // 一個訂單屬於一個用户
            .WithMany(u => u.Orders) // 一個用户有多個訂單
            .HasForeignKey(o => o.UserId); // 外鍵是UserId
    }
}

第二步:隱性發現:通過導航屬性識別關聯實體

即使沒在 DbContext 中聲明某個實體的 DbSet<T>,只要它被已聲明的實體通過導航屬性引用,DbContext 也會自動發現並納入模型。

比如:若刪除 public DbSet<Order> Orders { get; set; },但 User 中有 List<Order> OrdersDbContext 依然會識別 Order 實體(因為它是 User 的關聯實體)。

第三步:整合模型:OnModelCreating 最終確認

DbContext 會先基於 “默認約定 + 數據註解” 收集模型信息,再執行 OnModelCreating 方法,用 Fluent API 的配置補充 / 覆蓋原有規則,最終形成完整的模型元數據—— 這是後續轉換為數據庫表的核心依據。

將模型轉換為數據庫表

DbContext 識別出完整模型後,不會直接創建表,需通過 “遷移(Migration)” 功能將模型元數據轉換為數據庫的 DDL(建表 SQL),核心轉換規則如下:

核心轉換規則(默認約定)

模型元素 數據庫表 / 字段轉換規則
實體類名(如 User) 表名默認是實體名的複數形式(User→Users),可通過 [Table]/Fluent API 自定義
實體屬性(如 UserName) 列名默認和屬性名一致,類型自動映射(stringnvarchar (MAX)intintdecimaldecimal (18,2)
主鍵(Id) 自動設為主鍵約束,int/long 類型默認自增(SQL Server:IDENTITY (1,1)
外鍵(UserId) 自動創建外鍵約束,關聯主實體主鍵,默認開啓級聯刪除(刪除 User 時自動刪除其 Orders)
導航屬性(Orders) 不生成列,僅用於 EF Core 識別關係,驅動外鍵約束的創建

通過遷移生成實際表

執行以下命令,EF Core 會根據模型元數據生成建表 SQL 並執行:

# 1. 創建遷移文件:生成建表 SQL 腳本(存於項目 Migrations 文件夾)
Add-Migration InitialCreate

# 2. 應用遷移:執行 SQL,在數據庫中創建表
Update-Database

以下是 UserOrder 的表:

-- 1. 創建Users表(對應User實體)
CREATE TABLE [Users] (
    [Id] INT NOT NULL IDENTITY(1,1), -- 對應User.Id:主鍵+自增(EF Core int主鍵默認IDENTITY)
    [UserName] NVARCHAR(MAX) NULL,    -- 對應User.UserName:string默認映射nvarchar(MAX),可空
    [Age] INT NOT NULL,               -- 對應User.Age:int默認映射int,非空(EF Core值類型默認非空)
    CONSTRAINT [PK_Users] PRIMARY KEY ([Id]) -- 主鍵約束:對應User.Id為主鍵
);

-- 2. 創建Orders表(對應Order實體)
CREATE TABLE [Orders] (
    [Id] INT NOT NULL IDENTITY(1,1),          -- 對應Order.Id:主鍵+自增
    [OrderTitle] NVARCHAR(MAX) NULL,         -- 對應Order.OrderTitle:string→nvarchar(MAX),可空
    [Amount] DECIMAL(18, 2) NOT NULL,        -- 對應Order.Amount:decimal默認映射decimal(18,2),非空
    [UserId] INT NOT NULL,                   -- 對應Order.UserId:外鍵字段,關聯Users.Id
    CONSTRAINT [PK_Orders] PRIMARY KEY ([Id]), -- 主鍵約束
    -- 外鍵約束:對應導航屬性的一對多關係(Order.User + User.Orders)
    CONSTRAINT [FK_Orders_Users_UserId] FOREIGN KEY ([UserId]) 
        REFERENCES [Users] ([Id]) 
        ON DELETE CASCADE -- 級聯刪除:刪除User時自動刪除其關聯的Order(EF Core默認行為)
);

CRUD 操作

  • 新增:用 Add/AddRange 標記新增,SaveChanges() 提交,支持級聯新增;
  • 查詢:核心是 LINQ 語法 +Include 加載關聯數據,分頁用 Skip/Take,排序用 OrderBy
  • 更新:可 “查詢後修改”(自動跟蹤狀態)或 “無跟蹤更新”(高性能),無需手動調用 Update
  • 刪除:用 Remove/RemoveRange 標記刪除,注意級聯刪除的風險,務必先查詢再刪除(避免誤刪)。

Create(新增)

通過 Add/AddRange 標記實體為 “新增狀態”,調用 SaveChanges() 提交到數據庫(生成 INSERT SQL)。

  • 新增單個實體
using (var dbContext = new AppDbContext())
{
    // 1. 創建實體對象
    var newUser = new User
    {
        UserName = "張三",
        Age = 28
    };

    // 2. 標記為新增狀態(DbSet<T>.Add)
    dbContext.Users.Add(newUser);

    // 3. 提交更改(EF Core 生成 INSERT SQL 並執行)
    int affectedRows = dbContext.SaveChanges(); // 返回受影響的行數(此處為 1)
    Console.WriteLine($"新增用户成功,用户ID:{newUser.Id}"); // 新增後自動填充主鍵 Id
}
  • 新增關聯實體:通過導航屬性同時新增用户和其訂單(EF Core 自動處理外鍵賦值)
using (var dbContext = new AppDbContext())
{
    var newUser = new User
    {
        UserName = "李四",
        Age = 30,
        // 導航屬性賦值:關聯訂單
        Orders = new List<Order>
        {
            new Order { OrderTitle = "購買手機", Amount = 2999.99m },
            new Order { OrderTitle = "購買耳機", Amount = 199.99m }
        }
    };

    dbContext.Users.Add(newUser);
    dbContext.SaveChanges();
    Console.WriteLine($"新增用户ID:{newUser.Id},關聯訂單數:{newUser.Orders.Count}");
    // 訂單的UserId會自動填充為 newUser.Id,無需手動賦值
}
  • 批量增加
using (var dbContext = new AppDbContext())
{
    var userList = new List<User>
    {
        new User { UserName = "王五", Age = 25 },
        new User { UserName = "趙六", Age = 35 }
    };

    // AddRange:批量標記新增
    dbContext.Users.AddRange(userList);
    dbContext.SaveChanges();
    Console.WriteLine($"批量新增 {userList.Count} 個用户完成");
}

Read(查詢)

查詢是 CRUD 中最靈活的操作,核心是通過 LINQ 語法描述查詢條件,EF Core 自動轉換為 SELECT SQL。

  • 基礎查詢
using (var dbContext = new AppDbContext())
{
    // 1. 查詢所有用户(生成:SELECT * FROM Users)
    var allUsers = dbContext.Users.ToList();

    // 2. 查詢單個用户(按主鍵,找不到返回 null,推薦用 FirstOrDefault)
    var targetUser = dbContext.Users.FirstOrDefault(u => u.Id == 1);
    // 注意:SingleOrDefault要求結果只能是0或1條,多了會報錯;FirstOrDefault取第一條,更安全

    // 3. 條件查詢(年齡>25的用户,生成:SELECT * FROM Users WHERE Age > 25)
    var adultUsers = dbContext.Users.Where(u => u.Age > 25).ToList();

    // 4. 只查詢指定字段(避免SELECT *,提升性能)
    var userNames = dbContext.Users.Select(u => new { u.Id, u.UserName }).ToList();
}
  • 關聯數據查詢:默認情況下 EF Core 不會加載導航屬性(如 User.Orders),需用 Include 顯式加載。
using (var dbContext = new AppDbContext())
{
    // 1. 加載用户+關聯的所有訂單(生成 JOIN SQL)
    var userWithOrders = dbContext.Users
        .Include(u => u.Orders) // 關鍵:加載導航屬性 Orders
        .FirstOrDefault(u => u.Id == 1);
    if (userWithOrders != null)
    {
        Console.WriteLine($"用户{userWithOrders.UserName}有{userWithOrders.Orders.Count}個訂單");
    }

    // 2. 加載訂單+關聯的用户(反向導航)
    var orderWithUser = dbContext.Orders
        .Include(o => o.User)
        .FirstOrDefault(o => o.Id == 1);
    Console.WriteLine($"訂單{orderWithUser.Id}所屬用户:{orderWithUser.User.UserName}");
}
  • 分頁 + 排序查詢
using (var dbContext = new AppDbContext())
{
    int pageIndex = 1; // 頁碼(從 1 開始)
    int pageSize = 10; // 每頁條數

    var pagedUsers = dbContext.Users
        .OrderByDescending(u => u.Age) // 按年齡降序排序
        .Skip((pageIndex - 1) * pageSize) // 跳過前面的記錄
        .Take(pageSize) // 取指定條數
        .ToList();

    // 總條數(用於計算總頁數)
    int totalCount = dbContext.Users.Count();
    Console.WriteLine($"第{pageIndex}頁,共{totalCount}條數據");
}

Update(更新)

EF Core 跟蹤實體狀態,修改實體屬性後調用 SaveChanges(),自動生成 UPDATE SQL。

  • 基礎更新(查詢→修改→提交)
using (var dbContext = new AppDbContext())
{
    // 1. 先查詢要更新的實體(EF Core 開始跟蹤該實體)
    var userToUpdate = dbContext.Users.FirstOrDefault(u => u.Id == 1);
    if (userToUpdate == null) return;

    // 2. 修改屬性(EF Core自動標記為“修改狀態”)
    userToUpdate.Age = 29;
    userToUpdate.UserName = "張三_修改後";

    // 3. 提交更改(無需手動調用 Update,EF Core 已跟蹤狀態)
    dbContext.SaveChanges();
    Console.WriteLine("用户信息更新完成");
}
  • 無跟蹤更新:如果已知實體主鍵,可通過 Attach 手動標記狀態,避免額外的查詢操作。
using (var dbContext = new AppDbContext())
{
    // 1. 創建僅含主鍵和要修改字段的實體
    var userToUpdate = new User { Id = 1, Age = 30 };

    // 2. 附加到 DbContext 並標記為“修改狀態”
    dbContext.Users.Attach(userToUpdate);
    dbContext.Entry(userToUpdate).Property(u => u.Age).IsModified = true; // 僅標記 Age 為修改

    // 3. 提交更改
    dbContext.SaveChanges();
}
  • 批量更新
using (var dbContext = new AppDbContext())
{
    // 1. 查詢要批量更新的實體
    var usersToUpdate = dbContext.Users.Where(u => u.Age < 30).ToList();

    // 2. 批量修改
    foreach (var user in usersToUpdate)
    {
        user.Age += 1; // 年齡+1
    }

    // 3. 提交
    dbContext.SaveChanges();
}

Delete(刪除)

通過 Remove/RemoveRange 標記實體為 “刪除狀態”,調用 SaveChanges() 生成 DELETE SQL。

  • 單個實體刪除
using (var dbContext = new AppDbContext())
{
    // 1. 查詢要刪除的實體
    var userToDelete = dbContext.Users.FirstOrDefault(u => u.Id == 2);
    if (userToDelete == null) return;

    // 2. 標記為刪除狀態
    dbContext.Users.Remove(userToDelete);

    // 3. 提交更改
    dbContext.SaveChanges();
    Console.WriteLine("用户刪除完成");
}
  • 關聯實體刪除
using (var dbContext = new AppDbContext())
{
    var userToDelete = dbContext.Users.Include(u => u.Orders).FirstOrDefault(u => u.Id == 1);
    if (userToDelete == null) return;

    // 刪除用户 → 級聯刪除其所有訂單
    dbContext.Users.Remove(userToDelete);
    dbContext.SaveChanges();
    Console.WriteLine($"刪除用户{userToDelete.Id},同時刪除{userToDelete.Orders.Count}個訂單");
}
  • 批量刪除
using (var dbContext = new AppDbContext())
{
    // 1. 查詢要批量刪除的實體
    var ordersToDelete = dbContext.Orders.Where(o => o.Amount < 200).ToList();

    // 2. 批量標記刪除
    dbContext.Orders.RemoveRange(ordersToDelete);

    // 3. 提交
    dbContext.SaveChanges();
    Console.WriteLine($"批量刪除{ordersToDelete.Count}個訂單");
}

額外內容

在內存中的數據庫

EF Core 提供的 InMemory 數據庫是一個輕量級的內存數據庫模擬器,它不依賴任何真實數據庫引擎,數據僅存儲在應用內存中,程序重啓後數據全部丟失。

適合於單元測試、快速驗證模型 / CRUD 邏輯、原型開發。

  1. 使用前需先安裝 InMemory
dotnet add package Microsoft.EntityFrameworkCore.InMemory
  1. 配置 DbContext 使用內存數據庫
// OnConfiguring 方法
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        // 關鍵:使用內存數據庫,指定數據庫名稱(標識唯一的內存數據庫實例)
        optionsBuilder.UseInMemoryDatabase("MyDatabase");
    }
// 依賴注入配置方法
var services = new ServiceCollection();
services.AddDbContext<AppDbContext>(options =>
{
    // 配置內存數據庫,每次創建新實例(避免測試用例互相干擾)
    options.UseInMemoryDatabase("MyDatabase");
});

異步編程

數據庫操作(查詢 / 新增 / 更新 / 刪除)屬於 IO 密集型操作,同步編程會讓線程等待數據庫響應(期間線程閒置);而異步編程能讓線程在等待時去處理其他請求,大幅提升應用的併發處理能力。

EF Core 提供了一套和同步 API 對應的異步方法(後綴為 Async),語法和同步操作幾乎一致,只需配合 async/await 關鍵字使用。

異步 CRUD 語法和同步幾乎一致,僅需將同步方法替換為異步版本並添加 await

簡單且完整的案例

在開始之前,需要安裝如下兩個 Nuget 包:

dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.InMemory
  • 實體類:User.cs
namespace ConsoleApp1;

public class User
{
    public int Id { get; set; }
    public string? Name { get; set; }
    public int Age { get; set; }
}
  • 數據庫上下文管理器:AppDbContext.cs
using Microsoft.EntityFrameworkCore;

namespace ConsoleApp1;

public class AppDbContext : DbContext
{
    public DbSet<User> Users { get; set;}

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseInMemoryDatabase("MyDatabase");
    }
}
  • 啓動類:Program.cs
using ConsoleApp1;

using (var dbContext = new AppDbContext())
{
    // 新增
    var newUser = new User { Name = "張三", Age = 25 };
    dbContext.Users.Add(newUser);
    dbContext.SaveChanges();
    Console.WriteLine($"新增用户: {newUser.Name}, 年齡: {newUser.Age}, ID: {newUser.Id}");

    // 查詢
    var users = dbContext.Users.ToList();
    Console.WriteLine("查詢所有用户:");
    foreach (var user in users)
    {
        Console.WriteLine($"ID: {user.Id}, 姓名: {user.Name}, 年齡: {user.Age}");
    }

    // 更新
    var userToUpdate = dbContext.Users.FirstOrDefault(u => u.Name == "張三");
    if (userToUpdate != null)
    {
        userToUpdate.Age = 26;
        dbContext.SaveChanges();
        Console.WriteLine($"更新用户年齡為: {userToUpdate.Age}");
    }

    // 刪除
    var userToDelete = dbContext.Users.FirstOrDefault(u => u.Name == "張三");
    if (userToDelete != null)
    {
        dbContext.Users.Remove(userToDelete);
        dbContext.SaveChanges();
        Console.WriteLine($"刪除用户: {userToDelete.Name}");
    }
}

參考鏈接

  • Entity Framework Core 概述 - EF Core | Microsoft Learn
  • DbContext 生存期、配置和初始化 - EF Core | Microsoft Learn
  • 創建和配置模型 - EF Core | Microsoft Learn
  • 異步編程 - EF Core | Microsoft Learn
  • 數據庫提供程序 - EF Core | Microsoft Learn
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.