.Net 6服务端Blazor使用EF删除实体后数据库未更新问题求助
核心问题原因
- EF Core的变更跟踪机制仅感知实体本身的状态变更(新增/修改/删除),你对内存集合
clients执行Remove操作,只是将实体对象从自定义的List集合中移除引用,完全没有修改EF上下文对该实体的跟踪状态,上下文默认不会将这个操作识别为数据库删除操作,所以SaveChangesAsync不会生成对应的删除SQL语句。 - 你之前的理解存在偏差:EF查询返回的实体集合和EF上下文本身没有自动同步集合变更的机制,所有需要持久化到数据库的实体状态变更,都需要显式通知上下文。
Blazor服务端EF Core使用规范调整
你当前直接注入AppDbContext的方式存在潜在问题,Blazor服务端默认的Scoped生命周期对应整个用户连接会话,而不是传统WebAPI的单次请求级别,长期持有DbContext会导致如下问题:
- 变更跟踪的实体数量持续累积,内存占用上涨
- 多操作并发时容易出现实体跟踪冲突
- 上下文和数据库连接长时间占用无法及时释放
推荐用IDbContextFactory<AppDbContext>注入替代直接注入DbContext:
// Program.cs 注册示例 builder.Services.AddDbContextFactory<AppDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("你的数据库连接字符串键名"))); // 组件内注入 @inject IDbContextFactory<AppDbContext> DbFactory
对应查询和删除逻辑调整为:
private List<Customer> clients { get; set; } protected override async Task OnInitializedAsync() { using var context = await DbFactory.CreateDbContextAsync(); // 查询时用AsNoTracking关闭不必要的变更跟踪,提升性能 clients = await context.Customers.AsNoTracking().ToListAsync(); } private async Task DeleteCustomer(int CustomerId) { using var context = await DbFactory.CreateDbContextAsync(); var customer = await context.Customers.FindAsync(CustomerId); if (customer is not null) { // 显式通知上下文需要删除该实体 context.Remove(customer); await context.SaveChangesAsync(); // 同步更新内存列表,刷新前端UI clients.Remove(clients.First(f => f.Id == CustomerId)); } }
相关疑问澄清
- 显式调用
db.Remove(customer)本身就是EF Core删除操作的标准写法,不属于冗余操作,完全符合EF Core的设计规范,不存在不是最佳实践的说法。 - 如果你使用EF Core 7及以上版本,可以用执行原生删除SQL的方式跳过查询步骤,性能更高:
// 直接生成并执行删除SQL,不需要先查询实体 await context.Customers.Where(f => f.Id == CustomerId).ExecuteDeleteAsync();
执行后再同步移除内存列表中的对应项即可。
内容的提问来源于stack exchange,提问作者Guillermo Perez
相关产品推荐
相关产品推荐

