使用依赖注入时如何修复“在上一个操作完成之前在此上下文中启动的第二个操作......”?

joa*_*eza 5 c# entity-framework dbcontext

从数据库读取数据时出现此错误:

在前一个操作完成之前,在此上下文中启动了第二个操作。不保证任何实例成员都是线程安全的。

我有以下 ApplicationContext.cs:

public class ApplicationContext : Microsoft.EntityFrameworkCore.DbContext
{
    public ApplicationContext(DbContextOptions<ApplicationContext> options)
        : base(options)
    { }

    public DbSet<MyClass> MyClasses{ get; set; }
}   
Run Code Online (Sandbox Code Playgroud)

下面的 ApplicationContextFactory.cs

public class ApplicationContextFactory : IDesignTimeDbContextFactory<ApplicationContext>
{
    public ApplicationContext CreateDbContext(string[] args)
    {
        var builder = new DbContextOptionsBuilder<ApplicationContext>();
        var connection = "myConnectionString";

        builder.UseSqlServer(connection);

        return new ApplicationContext(builder.Options);
    }
}   
Run Code Online (Sandbox Code Playgroud)

以下 ServiceLoader.cs(我在其中声明 DI):

public static class ServiceLoader
{
    public static void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IRepository, Repository>();

        var connection = "myConnectionString";
        services.AddDbContext<ApplicationContext>(options => options.UseSqlServer(connection));
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,以下存储库,其中抛出异常:

public class Repository : IRepository
{
    private ApplicationContext _db;

    public Repository (ApplicationContext db)
    {
        _db = db;
    }

    public List<MyClass> Get()
    {
        _db.MyClasses.ToList();
    }
}
Run Code Online (Sandbox Code Playgroud)

我也尝试将 Repository 声明为 Transient 而不是 Singleton,但是抛出了类似的错误

'在配置上下文时尝试使用它。DbContext 实例不能在 OnConfiguring 中使用,因为此时它仍在配置中。如果在前一个操作完成之前在此上下文上启动第二个操作,则会发生这种情况。不保证任何实例成员都是线程安全的。

关于如何解决这个问题的任何想法?谢谢!

Rob*_*Rob 5

就我而言,我发现以下信息很有帮助:

https://docs.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext

并在启动时使用重载的 AddDbContext 方法将我的 Db 上下文的生命周期范围更改为瞬态:

services.AddDbContext<MyAppDbContext>(options => {
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection"));
        }, ServiceLifetime.Transient);
Run Code Online (Sandbox Code Playgroud)