You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 12:06:04