[英]Entity Framework Core 1.0 Connection Strings
我們正在開發一個不同的大型ASP.NET Core MVC 1.0應用程序。 我們的每個應用程序有4層,如下所示:
目前,在處理所有數據庫操作的存儲庫中,我們對DbContext中的數據庫連接字符串進行了硬編碼,如下所示:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
optionsBuilder.UseSqlServer("Data Source=somedatabase.database.windows.net;Initial Catalog=database;Integrated Security=False;User ID=username;Password=password;Connect Timeout=60;Encrypt=True;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False;MultipleActiveResultSets=true");
}
該項目作為獨立的ASP.NET Core 1.0項目位於MVC項目之外。 它還有一個空的Program.cs文件,它似乎是執行代碼到數據庫命令行所必需的(dotnet ef migrations add和dotnet ef database update)。
我們在DbConext中有一個硬編碼連接字符串的原因是因為當我們使用下面的代碼時,在執行dotnet ef命令時,我們得到一個對象引用未設置為對象異常的實例。
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
optionsBuilder.UseSqlServer(ConfigurationManager.ConnectionStrings["StandardDatabase"].ConnectionString);
}
但是,由於我們有一個Program.cs,如果我們為連接字符串添加Debug.WriteLine並運行項目,它會返回正確的連接字符串,如果我們在UI中的appsettings.json文件中設置連接字符串,用戶界面也將成功連接。
問題:上面提到的堆棧是我們用於幾個“Micro Apps”的東西,這意味着我們有幾個連接到多個數據庫的項目。 我們還希望利用Development,Staging和Production連接字符串。
如果我們使用Configuration Manager連接字符串,一切都適合日常操作; 但是,當我們想要將Entity Frameworks代碼用於數據庫命令行時,我們需要進入我們想要更新的每個存儲庫,並將DbContext更改為硬編碼連接字符串,執行命令,然后將它們更改回完成時,這變得非常麻煩。
問題:我們只是做錯了嗎?是否有一個首選實踐來設置Entity Framework Core 1.0堆棧,它允許我們不必手動更改DbContext但是充分利用配置文件?
任何方向將不勝感激!
EF Core旨在通過依賴注入進行配置。 依賴注入使您的DbContext保持干凈,並且獨立於環境的實現細節。
您的硬編碼連接字符串的初始解決方案將DbContext緊密耦合到數據庫所在位置的知識。 這顯然是一個問題。 但是您提出的解決方案將DbContext與特定配置文件的知識緊密結合在一起。 這也是一個問題。
要使DbContext獨立於環境細節,請創建一個構造函數,該構造函數接受DbContextOptions
參數並調用基類構造函數。
public class MyContext : DbContext
{
public MyContext(DbContextOptions options) :
base(options)
{
}
}
這樣做而不是覆蓋OnConfiguring
。 然后在主機應用程序的Startup.cs
中初始化它。 這就是配置文件的知識所屬的地方。
public class Startup
{
private IConfigurationRoot _configuration;
public Startup(IHostingEnvironment env)
{
_configuration = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json")
.Build();
}
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IConfigurationRoot>(_configuration);
services.AddDbContext<MyContext>(options => options
.UseSqlServer(_configuration.GetConnectionString("MyContext")));
}
}
現在,您可以從任何地方使用您的DbContext。
答案:我實際上比實際情況要困難得多。 我按照Juunas的建議,在我的Repository DbContext類中添加了以下代碼:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// get the configuration from the app settings
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
// define the database to use
optionsBuilder.UseSqlServer(config.GetConnectionString("StandardDatabase"));
}
這與dotnet ef命令行工具完美配合,而且我的MVC UI在我的startup.c中堅持使用以下默認代碼的多環境設置也很好。
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddJsonFile("project.json", optional: true, reloadOnChange: true);
IDbContextFactory也可能有所幫助。 EF命令行工具和DI可以使用此工廠來創建DBContext的實例。 設計時服務(例如,遷移)將發現此接口的實現與派生上下文在同一程序集中。
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
namespace MyProject
{
public class BloggingContextFactory : IDbContextFactory<BloggingContext>
{
public BloggingContext Create()
{
var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
optionsBuilder.UseSqlite("Filename=./blog.db");
return new BloggingContext(optionsBuilder.Options);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.