在Asp.Net Core中動態更改連接字符串

asp.net asp.net-core c# entity-framework-core

我想在控制器中更改sql連接字符串,而不是在ApplicationDbContext中。我正在使用Asp.Net Core和Entity Framework Core。

例如:

public class MyController : Controller {
    private readonly ApplicationDbContext _dbContext
    public MyController(ApplicationDbContext dbContext)
    {
        _dbContext = dbContext;
    }
    private void ChangeConnectionString()
    {
    // So, what should be here?
    } }

我怎樣才能做到這一點?

一般承認的答案

我們有一個類似於你的案例。我們所做的是在Startup類的ConfigureServices方法中使用IServiceCollectionimplementationfactory重載,如下所示:

//First register a custom made db context provider
services.AddTransient<ApplicationDbContextFactory>();
//Then use implementation factory to get the one you need
services.AddTransient(provider => provider.GetService<ApplicationDbContextFactory>().CreateApplicationDbContext());

我現在很難為你實現CreateApplicationDbContext,因為它完全取決於你想要什麼。但是,一旦你確定了你想要如何完成它的部分,該方法的基礎知識應該是這樣的:

public ApplicationDbContext CreateApplicationDbContext(){
  //TODO Something clever to create correct ApplicationDbContext with ConnectionString you need.
} 

實現此功能後,您可以像在構造函數中一樣在控制器中註入正確的ApplicationDbContext:

public MyController(ApplicationDbContext dbContext)
{
    _dbContext = dbContext;
}

或者控制器中的動作方法:

public IActionResult([FromServices] ApplicationDbContext dbContext){
}

無論你實現細節,訣竅是實現工廠將在每次注入時構建ApplicationDbContext。

告訴我您是否需要更多幫助來實施此解決方案。

更新#1 Yuriy N.詢問AddTransient和AddDbContext之間有什麼區別,這是一個有效的問題......事實並非如此。讓我解釋。

這與原始問題無關。

但是......話雖如此,實施自己的“實施工廠”(這是我要回答的最重要的事情),在這種情況下,實體框架可能比我們需要的更棘手。

但是,通過這些問題,我們現在可以幸運地查看GitHub中的源代碼,因此我查看了AddDbContext的確切功能。好吧......那真的不難。這些'add'(和'use')擴展方法只不過是方便方法,請記住。因此,您需要添加AddDbContext所做的所有服務以及選項。也許您甚至可以重用AddDbContext擴展方法,只需在實現工廠中添加自己的重載。

所以,回到你的問題。 AddDbContext執行一些EF特定的東西。正如您所看到的,它們將允許您在以後的版本中使用一生(瞬態,單例)。 AddTransient是Asp.Net Core,允許您添加所需的任何服務。而且你需要一個實施工廠。

這會讓它更清楚嗎?


熱門答案

我可以通過將連接字符串邏輯移動到OnConfiguring方法來更改每個請求的連接字符串。

Startup.cs#ConfigureServices services.AddDbContext<MyDbContext>();方法: services.AddDbContext<MyDbContext>();

在MyDbContext.cs中,我添加了我需要注入構造函數的服務。

    private IConfigurationRoot _config;
    private HttpContext _httpContext;

    public MyDbContext(DbContextOptions options, IConfigurationRoot config, IHttpContextAccessor httpContextAccessor) 
          : base(options)
    {
        _config = config;
        _httpContext = httpContextAccessor.HttpContext;
    }

然後重寫OnConfiguring:

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        var connString = BuildConnectionString(); // Your connection string logic here

        optionsBuilder.UseSqlServer(connString);
    }


Related

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