2016-12-14 28 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)。

如果我想刪除硬編碼的連接字符串,我面臨着以下問題:

  • ,如果我嘗試注入IConfigurationApplicationDbContext,遷移將會失敗No parameterless constructor defined for this object.
  • 沒有注入的東西我無法找到一種從配置文件中讀取信息的方式

我該如何繼續?

謝謝。

[編輯]

Startup.cs我已經配置的連接字符串,並將其正常工作時(runtime):

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<>,我不知道如何注入配置。後

編輯試圖IOptions <>與ApplicationDbContext

我曾嘗試提出解決方案,但我不能讓它工作,因爲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

我面臨同樣的問題,我解決它以下列方式:

  1. 與服務集合中的連接字符串註冊選項
  2. 進樣選擇到的DbContext
  3. 用戶連接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); 

     ... 
    } 
} 

然後你就可以使用它作爲休耕(這是控制器的例子,但你可以做同樣的用的DbContext):

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'的路徑。目前我正在使用'AppContext.BaseDirectory',它返回'full_path_to_appname \ bin \ Debug \ netcoreapp1.1 \ win7-x64',我剝離了所有以'\ bin'開頭的東西。 – Alexei

相關問題