ASP.NetコアのSqlServerDBContextOptionsExtensionsから接続文字列を取得するにはどうすればよいですか

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

質問

私はASP.Net Core APIを構築しており、DBContextOptionsから接続文字列を取得する方法を見つけることができませんでした。

私は以下のようにstartup.csにDBContextを持っています。

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddApplicationInsightsTelemetry(Configuration);

    services.AddEntityFrameworkSqlServer()
        .AddDbContext<MainContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MainConnection")));

    services.AddMvc()
       .AddJsonOptions(opt =>
        {
            opt.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
        });
}

私のContextクラスでは、私は次のコンストラクタを持っています。

public MainContext(DbContextOptions<MainContext> options) : base(options)
{

}

DBContextクラスのOnConfiguringメソッドに実際の接続文字列を追加しない限り動作しません。

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    //TODO Move connection string to a secure location
    optionsBuilder.UseSqlServer(@"Server= .....");

}

Configuration.GetConnectionString( "MainConnection")の値をデバッグして調べると、Startup.csがappsettings.jsonファイルから正しい接続文字列を取得していることがわかります。

DIを介してDbContextクラスにオプションを渡すと接続文字列が渡されたと思いますが、DbContectクラスはOnConfiguringメソッドのoptionBuilder.UseSqlServer()を持たないと動作しません。

私はこのSO post https://stackoverflow.com/questions/33532599/asp-net-5-multiple-dbcontext-problemsを見つけました。これは、オプションプロパティから接続文字列を抽出する次のコードを使用することについて話しています

public ResourceDbContext(DbContextOptions options) : base(options)
{
    _connectionString = ((SqlServerOptionsExtension)options.Extensions.First()).ConnectionString;
}


protected override void OnConfiguring(DbContextOptionsBuilder options)
{
    options.UseSqlServer(_connectionString);
}  

しかし、私はそれを使用しようとすると、もはやオプションのFirst()メソッドが存在しないことがわかります。拡張

だから、私の最初の質問は...

OnConfiguringメソッドで接続文字列を追加しなくてもDBContextクラスが機能しないのはなぜですか

私の2番目の質問は...

OnConfiguringメソッドで接続文字列が必要な場合、OnBuilder.UseSqlServer(@ "Server = .....")のOnConfiguringメソッドで明示的に指定する必要はなく、DbContextOptionsオプションオブジェクトから取得するにはどうすればよいですか? ;

受け入れられた回答

appsettings.json中で、次のように作成します:

{
     "Database" : {
          "ConnectionString" : "..."
      }
}

次に、 ConfigureServices内で次の操作を行います。

services.AddSingleton(_ => Configuration);

これは基本的にIConfigurationRootプロパティをIConfigurationRootます。次のようにすればどこにでも挿入でき、接続文字列にアクセスできます:

private readonly IConfigurationRoot configuration;
private IDbConnection dbConnection { get; }

public Example(IConfigurationRoot configuration)
{
     this.Configuration = configuration;
     dbConnection = new SqlConnection(this.configuration.GetConnectionString("..."));
}

これはちょっと奇妙な構造ですが、実際にConnectionStringを別のクラスに渡すか、注入するメソッドがありますが、これはあなたのために実証しています。しかし、Entity Framework 7には接続文字列を直接受け入れるファクトリがあると私は思っています。うまくいけば、これはあなたを助けます。

Entity Frameworkでは、これはConfigureServices内部にあるはずです。

services.AddSingleton<dbContext>(_ => new dbContext(Configuration.GetConnectionString("...")));
public class dbContext : DbContext
{
     public dbContext(string dbConnection) : base(dbConnection)
     {

     }
}

いくつかの追加のドキュメント


人気のある回答

少なくともEF Core 1.1では、 FindExtension<SqlServerOptionsExtension>()を使用する必要があります。

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure.Internal;

namespace MyNamespace
{
    public class MyContext : DbContext
    {
        public MyContext(DbContextOptions<MyContext> options) : base(options)
        {
            var sqlServerOptionsExtension = 
                   options.FindExtension<SqlServerOptionsExtension>();
            if(sqlServerOptionsExtension != null)
            {
                string connectionString = sqlServerOptionsExtension.ConnectionString;
            }
        }
    }
}

あなたのStartup.csopt.UseInMemoryDatabase()を使用している場合、nullチェックがあります。



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ