Dispose() удается удалить файл базы данных, но DisposeAsync() завершается с ошибкой, почему?C#

Место общения программистов C#
Ответить
Anonymous
 Dispose() удается удалить файл базы данных, но DisposeAsync() завершается с ошибкой, почему?

Сообщение Anonymous »

Я хочу, чтобы каждый интеграционный тест создавал уникальное имя файла базы данных и удалял его в конце теста.

Код: Выделить всё

using Microsoft.EntityFrameworkCore;

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

public record Person(int Id);
public class AppDbContext(DbContextOptions o) : DbContext(o)
{
public DbSet People { get; set; }
}
public interface IWebApiMarker;
Чтобы облегчить переключение между DisposeAsync() и Dispose(), я создал переменную компиляции 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 _factory;
protected BaseTest()
{
_factory = new WebApplicationFactory();
using var scope = _factory.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService();
db.Database.EnsureCreated();
}
#if SYNC
public void Dispose()
{
using var scope = _factory.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService();
db.Database.EnsureDeleted();
_factory.Dispose();
}
#else
public async ValueTask DisposeAsync()
{
using var scope = _factory.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService();
db.Database.EnsureDeleted();
await _factory.DisposeAsync();
}
#endif
}
Я не понимаю, почему DisposeAsync() не может удалить файл базы данных в конце каждого теста.
Неудачные попытки
  • Кэширование базы данных разрешено в BaseTest() как частная база данных AppDbContext только для чтения и повторное ее использование (чтобы убедиться в этом) это тот же объект) в DisposeAsync() не помогает.
  • Замена db.Database.EnsureDeleted() на await db.Database.EnsureDeletedAsync()< /code> не помогает.
  • Вызов DisposeAsync() в тестовом методе, [Факт] public async Task Test() => await DisposeAsync(); не помогает. Он выдает исключение:
System.ObjectDisposeException: невозможно получить доступ к удаленному экземпляру контекста. Распространенной причиной этой ошибки является удаление экземпляра контекста, который был разрешен в результате внедрения зависимостей, а затем попытка использовать тот же экземпляр контекста в другом месте вашего приложения. Это может произойти, если вы вызываете Dispose для экземпляра контекста или заключаете его в оператор using. Если вы используете внедрение зависимостей, вы должны позволить контейнеру внедрения зависимостей позаботиться об удалении экземпляров контекста.


Подробнее здесь: https://stackoverflow.com/questions/788 ... -fails-why
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»