Asp.Netコアで動的に接続文字列を変更する

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

質問

私は、ApplicationDbContextではなく、コントローラ内のSQL接続文字列を変更したい。 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メソッドでIServiceCollectionの 実装上のオーバーロードを使用することです。

//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を構築します。

このソリューションを実装するのにもっと助けが必要な場合は教えてください。

Update#1 Yuriy N.は、有効な質問であるAddTransientとAddDbContextの違いを尋ねました...そしてそうではありません。私に説明させてください。

元の質問には関係ありません。

しかし、それを言って、あなた自身の '実装ファクトリ'(私の答えを書き留めることが最も重要なことです)を実装することは、この場合、エンティティフレームワークでは、私たちが必要としていたものより少し難解です。

しかし、このような質問で、GitHubのソースコードを見れば幸いなことになるので、 AddDbContextが正確に何をしているのか調べました。そしてまあ...それは本当に難しいことではありません。これらの「追加」(および「使用」)拡張メソッドは、便利なメソッド以外何もありません。したがって、AddDbContextが行うすべてのサービスとオプションを追加する必要があります。おそらく、あなたはAddDbContext拡張メソッドを再利用することもできます。実装ファクトリで独自のオーバーロードを追加するだけです。

だから、あなたの質問に戻ってくる。 AddDbContextはいくつかのEF固有の処理を行います。あなたが見ることができるように、彼らはあなたが後のリリース(一時的、シングルトン)で生涯を過ごせるようにするつもりです。 AddTransientはAsp.Net Coreで、必要なサービスを追加できます。そして、あなたは実装工場が必要です。

これはより明確になりますか?


人気のある回答

接続文字列ロジックをOnConfiguringメソッドに移動することによって、各リクエストの接続文字列を変更することができました。

Startup.cs#ConfigureServicesメソッド: 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は合法ですか? はい、理由を学ぶ