EF 7(核心)。像AddTransient一樣創建DBContext


根據文檔,我配置DbContext如下面的DI在範圍內註冊它(每個http請求)

services.AddEntityFramework()
   .AddSqlServer()
   .AddDbContext<DBData>(options => {
        options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]);                    
    }
);

當我嘗試在另一個線程中訪問它時出現問題。

services.AddEntityFramework()
   .AddSqlServer()
   .AddDbContext<DBData>(options => {
        options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]);                    
    }
);

我想為每個調用配置DbContext創建(AddTransition)。它可以讓我編寫下一個代碼

services.AddEntityFramework()
   .AddSqlServer()
   .AddDbContext<DBData>(options => {
        options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]);                    
    }
);

所以現在如果我想為每個請求創建DBContext,我將使用IUnitOfWorkFactoryPerRequest ,當我想在某些後台線程中使用IUnitOfWorkFactoryPerCall我可以使用IUnitOfWorkFactoryPerCall

一般承認的答案

我的臨時解決方案我創建了單例,可以“以瞬態方式”創建上下文

public class AppDependencyResolver
{
    private static AppDependencyResolver _resolver;

    public static AppDependencyResolver Current
    {
        get
        {
            if (_resolver == null)
                throw new Exception("AppDependencyResolver not initialized. You should initialize it in Startup class");
            return _resolver;
        }
    }

    public static void Init(IServiceProvider services)
    {
        _resolver = new AppDependencyResolver(services);
    }

    private readonly IServiceProvider _serviceProvider;

    public AppDependencyResolver(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public IUnitOfWorkFactory CreateUoWinCurrentThread()
    {
        var scopeResolver = _serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope();
        return new UnitOfWorkFactory(scopeResolver.ServiceProvider.GetRequiredService<DBData>(), scopeResolver);
    }
}

然後我在Startup Configure方法中調用init方法

public class AppDependencyResolver
{
    private static AppDependencyResolver _resolver;

    public static AppDependencyResolver Current
    {
        get
        {
            if (_resolver == null)
                throw new Exception("AppDependencyResolver not initialized. You should initialize it in Startup class");
            return _resolver;
        }
    }

    public static void Init(IServiceProvider services)
    {
        _resolver = new AppDependencyResolver(services);
    }

    private readonly IServiceProvider _serviceProvider;

    public AppDependencyResolver(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public IUnitOfWorkFactory CreateUoWinCurrentThread()
    {
        var scopeResolver = _serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope();
        return new UnitOfWorkFactory(scopeResolver.ServiceProvider.GetRequiredService<DBData>(), scopeResolver);
    }
}

畢竟我可以在一些後台線程中調用AppDependencyResolver.Current.CreateUoWinCurrentThread()

如果有人能提供更優雅的解決方案,我將不勝感激。





許可下: CC-BY-SA
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因