3

我建立一個ASP.Net核心API,我一直沒有能夠找到一種方法來從DBContextOptions獲取連接字符串。我如何從SqlServerDBContextOptionsExtensions在ASP.Net核心

我在我的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= ....."); 

} 

我可以看到Startup.cs從appsettings.json文件中獲取正確的連接字符串時,我調試和檢查Configuration.GetConnectionString值(「MainConnection」)。

我認爲,經過選擇進入的DbContext類通過DI會通過連接字符串,但DbContect類沒有工作,除非我有optionBuilder.UseSqlServer()在OnConfiguring方法。

我發現這個SO發佈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); 
} 

連接字符串,但是當我嘗試使用它,我發現有不再在options.Extensions

所以,我的第一個問題是首先()方法...

爲什麼沒有的DbContext類的工作,而無需添加連接字符串中的OnConfiguring方法

我的第二個問題是...

如果連接字符串在OnCOnfiguring方法所需要的,我怎麼能得到它從DbContextOptions選項對象,而不是明確地提供它在OnConfiguring方法 - > optionsBuilder .UseSqlServer(@「Server = .....」);

回答

2

裏面的你appsettings.json您將創建以下文件:

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

內。然後你ConfigureServices你會做到以下幾點:

services.AddSingleton(_ => Configuration); 

這將基本上填充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有一個工廠直接接受連接字符串。希望這可以幫助你。

在實體框架應該是你這樣的ConfigureServices內:

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

    } 
} 

一些額外的documentation

0

至少爲EF核心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.cs

使用 opt.UseInMemoryDatabase()