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

Dispose()可成功删除DB文件,为何DisposeAsync()执行失败?

问题描述

我希望每个集成测试都创建唯一的数据库文件名,并在测试结束时将其删除。

应用代码

using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);
var constr = $"DataSource={Guid.NewGuid()}.db";
builder.Services.AddDbContext<AppDbContext>(o => o.UseSqlite(constr));
var app = builder.Build();
app.Run();

public record Person(int Id);
public class AppDbContext(DbContextOptions<AppDbContext> o) : DbContext(o)
{
    public DbSet<Person> People { get; set; }
}
public interface IWebApiMarker;

为便于在Dispose()和DisposeAsync()间切换,我创建了编译变量SYNC,仅用于诊断,不用于生产环境。

测试代码

#define SYNC
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;

namespace WebApi.Test;

public class Test_1 : BaseTest
{
    [Fact] public async Task Test() => await Task.Delay(2000);
}

#if SYNC
public abstract class BaseTest : IDisposable
#else
public abstract class BaseTest : IAsyncDisposable
#endif
{
    private readonly WebApplicationFactory<IWebApiMarker> _factory;
    protected BaseTest()
    {
        _factory = new WebApplicationFactory<IWebApiMarker>();
        using var scope = _factory.Services.CreateScope();
        var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
        db.Database.EnsureCreated();
    }
#if SYNC
    public void Dispose()
    {
        using var scope = _factory.Services.CreateScope();
        var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
        db.Database.EnsureDeleted();
        _factory.Dispose();
    }
#else
    public async ValueTask DisposeAsync()
    {
        using var scope = _factory.Services.CreateScope();
        var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
        db.Database.EnsureDeleted();
        await _factory.DisposeAsync();
    }
#endif
}

我无法理解为何DisposeAsync()无法在每个测试结束时删除数据库文件。

已尝试的无效方案

  • 将BaseTest()中解析的db缓存为private readonly AppDbContext db并在DisposeAsync()中复用(确保为同一对象),无效果。
  • 将db.Database.EnsureDeleted()替换为await db.Database.EnsureDeletedAsync(),无效果。
  • 在测试方法中调用DisposeAsync(),即[Fact] public async Task Test() => await DisposeAsync();,无效果且抛出异常:

System.ObjectDisposedException : 无法访问已释放的上下文实例。此错误的常见原因是释放了从依赖注入解析的上下文实例,之后又尝试在应用程序其他地方使用同一实例。这可能是因为您调用了上下文实例的“Dispose”方法,或将其包装在using语句中。若使用依赖注入,应让容器负责上下文实例的释放。


内容的提问来源于stack exchange,提问作者D G

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 03:27:25