前言
在本篇文章中,着重介紹如何使用 Entity Framework Core,不過多涉及底層細節。
Entity Framework Core(簡稱 EF Core)是微軟為.NET 平台打造的輕量級、跨平台對象關係映射(ORM)框架,以編寫 C# 對象代碼的方式操作各類數據庫,無需大量手寫原生 SQL 語句。
其中有兩大概念,也是本文要講述的內容:
- DbContext 配置和初始化
- 模型的創建與使用
DbContext
DbContext 是 EF Core 中連接 C# 代碼與數據庫的核心橋樑類(需要繼承 EF Core 的 DbContext 基類自定義),所有對數據庫的增刪改查操作,都必須通過它來完成。
它的核心作用可以概括為 3 點:
- 管理數據庫連接:自動處理和數據庫的連接建立、釋放,無需你手動寫連接代碼;
- 提供表操作入口:通過
DbSet<T>屬性(比如DbSet<User>)對應數據庫的一張表,是操作表的唯一入口; - 翻譯與執行:把對 C# 實體類的 LINQ 操作(比如
Add新增、Where查詢)自動轉換成 SQL 語句,提交到數據庫執行。
DbSet<T>是 EF Core 提供的泛型集合類型,泛型參數T必須是定義的實體類。
模型
EF Core 裏的 “模型”,本質是程序中所有實體類、實體間關係,以及這些實體與數據庫表 / 字段映射規則的整體描述。
它的核心作用可以概括為兩點:
- 是 EF Core 的認知基礎:EF Core 只有先通過模型知道 “User 類對應 Users 表、Id 屬性對應主鍵字段、一個用户對應多個商品”,才能正確把 C# 操作(比如新增用户)翻譯成對應的 SQL 語句;
- 是代碼與數據庫的契約:不管是從代碼生成數據庫(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 註冊到依賴注入容器,由容器統一管理配置和生命週期,避免硬編碼和手動管理資源。
- 自定義
DbContext(無需重寫OnConfiguring)
using Microsoft.EntityFrameworkCore;
public class AppDbContext : DbContext
{
// 構造函數接收 DI 容器傳入的配置(核心)
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
// 定義DbSet
public DbSet<User> Users { get; set; }
}
- 在
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> Orders,DbContext 依然會識別 Order 實體(因為它是 User 的關聯實體)。
第三步:整合模型:OnModelCreating 最終確認
DbContext 會先基於 “默認約定 + 數據註解” 收集模型信息,再執行 OnModelCreating 方法,用 Fluent API 的配置補充 / 覆蓋原有規則,最終形成完整的模型元數據—— 這是後續轉換為數據庫表的核心依據。
將模型轉換為數據庫表
DbContext 識別出完整模型後,不會直接創建表,需通過 “遷移(Migration)” 功能將模型元數據轉換為數據庫的 DDL(建表 SQL),核心轉換規則如下:
核心轉換規則(默認約定)
| 模型元素 | 數據庫表 / 字段轉換規則 |
|---|---|
| 實體類名(如 User) | 表名默認是實體名的複數形式(User→Users),可通過 [Table]/Fluent API 自定義 |
| 實體屬性(如 UserName) | 列名默認和屬性名一致,類型自動映射(string→nvarchar (MAX)、int→int、decimal→decimal (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
以下是 User 和 Order 的表:
-- 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 邏輯、原型開發。
- 使用前需先安裝
InMemory包
dotnet add package Microsoft.EntityFrameworkCore.InMemory
- 配置 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