EF Core Remove方法怎么用 EF Core删除实体教程

来源:这里教程网 时间:2026-02-21 17:35:21 作者:

EF Core 的

Remove
方法用于标记一个实体为“待删除”,真正执行删除操作要等到调用
SaveChanges()
SaveChangesAsync()
时才发生。它不是直接发 SQL 删除语句,而是走变更追踪流程——所以用法和注意事项比看起来更关键。

删除单个已知主键的实体(断开模式)

适用于你**只知道 ID、没从数据库查过该实体**的场景。比如前端传了个 ID 要删,你不想先查再删(避免两次数据库往返):

手动构造一个只带主键值的实体实例,传给
context.Remove()
EF Core 会尝试按主键去数据库删对应行;如果该主键在表中不存在,
SaveChanges()
会抛出
DbUpdateConcurrencyException
,提示“预期影响 1 行,实际影响 0 行”
示例:
var student = new Student { StudentId = 100 };<br>context.Remove(student);<br>await context.SaveChangesAsync();

删除已查询出来的实体(追踪模式)

这是最安全、最推荐的方式:先用

Find()
FirstOrDefault()
等方法从数据库加载实体,再删:

实体处于
Unchanged
状态,
Remove()
会将其状态改为
Deleted
即使数据在你查询后被别人删了,
SaveChanges()
仍会报并发异常,但你能明确知道是“查到了但已被删”,而不是“根本不存在”
示例:
var dept = await context.Departments.FindAsync(5);<br>if (dept != null)<br>{<br>    context.Remove(dept);<br>    await context.SaveChangesAsync();<br>}

批量删除多个实体

RemoveRange()
一次删多个,支持传入集合或多个参数:

可以传
List<t></t>
、数组,甚至两个实体(如
RemoveRange(e1, e2)
同样遵循“断开删需确保主键存在,追踪删更安全”的原则 注意:它仍是逐条生成 DELETE 语句,**不适合清空大表**;大数据量建议用原生 SQL
TRUNCATE
DELETE FROM
示例:
var toDelete = context.Students.Where(s => s.Status == "Inactive").ToList();<br>context.RemoveRange(toDelete);<br>await context.SaveChangesAsync();

级联删除与外键行为

如果实体有关联子项(如 Department 有多个 Employee),删父实体时子项是否自动删,取决于你在

OnModelCreating
中配置的
OnDelete()
行为:

DeleteBehavior.Cascade
:删 Department 同时删所有关联 Employee
DeleteBehavior.SetNull
:Employee.DepartmentId 设为 NULL(要求字段可空)
DeleteBehavior.Restrict
:禁止删,除非先清空子项
配置后必须重新运行
dotnet ef migrations add
update

基本上就这些。核心就两点:删之前尽量确认实体存在,大表别用 RemoveRange 硬扛。

相关推荐