2016-12-14 10 views
2

ASP.NET Core 1.1アプリケーションを使用していて、構成ファイルから接続文字列を読み取ろうとしています。構成ファイル(appsettings.json)から読み取るデータベースコンテキストのASP.NETコア実行マイグレーション

public class ApplicationDbContext : DbContext, IDbContextFactory<ApplicationDbContext> 
{ 
    public ApplicationDbContext() 
    { 
    } 

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) 
    { 
    } 

    protected override void OnModelCreating(ModelBuilder builder) 
    { 
     base.OnModelCreating(builder); 
    } 

    public ApplicationDbContext Create(DbContextFactoryOptions options) 
    { 
     var builder = new DbContextOptionsBuilder<ApplicationDbContext>(); 

     string connString = "some hardcoded connection string"; 
     builder.UseSqlServer(connString); 
     return new ApplicationDbContext(builder.Options); 
    } 
} 

マイグレーションを実行すると、(例えばdotnet ef database update)正常に動作します:

私のデータベースコンテキストクラスには、次のようになります。

私はハードコードされた接続文字列を削除したい場合は、私は次のような問題直面しています:私はApplicationDbContextIConfigurationを注入しようとした場合、移行は、私が見つけることができない何かを注入せずにNo parameterless constructor defined for this object.

  • で失敗します

    • を構成ファイルから情報を読み取る方法

    どうすればよいですか?

    ありがとうございました。

    [EDIT] Startup.cs

    私は、接続文字列を設定していると、それは(ランタイム)が正しく動作します:

    public void ConfigureServices(IServiceCollection services) 
    { 
        // Add framework services. 
        //services.AddApplicationInsightsTelemetry(Configuration); 
    
        string connString = ConfigurationExtensions.GetConnectionString(Configuration, "DefaultConnection"); 
        services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connString)); 
    
        services.AddMvc(); 
    } 
    

    問題はdotnet migrationsは、データベースコンテキストにおけるパラメータなしのコンストラクタを必要とするように思われることですIDbContextFactory<>を実装するには、設定を注入する方法がわかりません。

    編集ApplicationDbContext

    とIOptions <>を試した後、私は提案された解決策を試してみましたが、私はdotnet migrationは、デフォルトコンストラクタを呼び出しますので、それを動作させることはできません。

    public class ApplicationDbContext : DbContext, IDbContextFactory<ApplicationDbContext> 
    { 
        private IOptions<DefaultConnectionValue> ConnOptions; 
        private string connectionString; 
    
        public ApplicationDbContext() 
        { 
         Console.WriteLine("Default constructor was called"); 
        } 
    
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IOptions<DefaultConnectionValue> connOptions) : base(options) 
        { 
         ConnOptions = connOptions; 
         connectionString = connOptions.Value.Value; 
    
         Console.WriteLine($"Injected connection string = {connectionString}"); 
        } 
    
        protected override void OnModelCreating(ModelBuilder builder) 
        { 
         base.OnModelCreating(builder); 
        } 
    
        public ApplicationDbContext Create(DbContextFactoryOptions options) 
        { 
         var builder = new DbContextOptionsBuilder<ApplicationDbContext>(); 
    
         //string connString = ConfigurationExtensions.GetConnectionString(null, "DefaultConnection"); 
         builder.UseSqlServer(connectionString); 
         return new ApplicationDbContext(builder.Options, ConnOptions); 
        } 
    
  • +0

    をしかし、あなたはConfigureServicesに追加しました:services.AddDbContext (オプション=>options.UseSqlServer(Configuration.GetConnectionString( "DefaultConnection"))); https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/intro – Alexan

    +0

    @Alex - あなたの質問に答えるために質問を編集しました。 – Alexei

    答えて

    2

    私は同じ問題に直面していたし、私は次の方法でそれを解決:

  • 注入するオプションDBContext
  • ユーザーの接続にサービスコレクション内の接続文字列と

    1. 登録オプションをDBContextパラメータなしコンストラクタの文字列

    移行によって必要とされるパラメータのないコンストラクタが必要です。(それはコントローラの例ですが、あなたはDBContextと同じことを行うことができます)

    public class Startup 
    { 
        public Startup(IHostingEnvironment env) 
        { 
         // Set up configuration sources. 
         var builder = new ConfigurationBuilder() 
          .SetBasePath(env.ContentRootPath) 
          .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); //let's assume that here you have your connection string 
    
         Configuration = builder.Build(); 
        } 
    
        public IConfigurationRoot Configuration { get; set; } 
    
        public void ConfigureServices(IServiceCollection services) 
        { 
         // Adds services required for using options. 
         services.AddOptions(); 
    
         // Register the IConfiguration instance which MyOptions binds against. 
         services.Configure<MyOptions>(Configuration); 
    
         ... 
        } 
    } 
    

    そしてあなたに休耕それを使用することができます:ここで

    を使用すると、構成設定を登録することができる方法である

    public class HomeController : Controller 
    { 
        private readonly MyOptions _optionsAccessor; 
    
        public HomeController(IOptions<MyOptions> optionsAccessor) 
        { 
         //injection of your configuration object with connection string 
         _optionsAccessor = optionsAccessor.Value; 
        } 
    
        public IActionResult Index() 
        { 
         var option1 = _optionsAccessor.Option1; 
         var option2 = _optionsAccessor.Option2; 
         return Content($"option1 = {option1}, option2 = {option2}"); 
        } 
    } 
    

    設定の使用方法の詳細については、Configurationをご覧ください。

    UPDATE:

    あなたはまた違ったアプローチを試すことができます - DBContextコンストラクタの内部の設定を読み込む:

    public class ApplicationDbContext : DbContext, IDbContextFactory<ApplicationDbContext> 
    { 
        private string connectionString; 
    
        public ApplicationDbContext() 
        { 
         var builder = new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); //let's assume that here you have your connection string 
         var configuration = builder.Build(); 
    
         connectionString = ""; //FILL THE CONNECTION STRING FROM THE CONFIGURATION OBJECT 
        } 
    
        ... 
    } 
    
  • +0

    私は解決策を提案しようとしましたが、私はまだデータベースコンテキストでオプションを注入することに固執しています。 'dotnet migrations'はデフォルトのコンストラクタのみを呼び出し、何も注入できません。私は質問を編集しました。ありがとう。 – Alexei

    +0

    それは動作します。しかし、私は 'appsettings.json'への道を得るためのまともな方法を見つけなければなりません。現在、 'full_path_to_appname \ bin \ Debug \ netcoreapp1.1 \ win7-x64'を返す' AppContext.BaseDirectory'を使用していますが、 '\ bin'で始まるすべてを取り除いています。 – Alexei

    関連する問題