[英]Get ConnectionString from appsettings.json instead of being hardcoded in .NET Core 2.0 App
我有以下 class in.NET Core2.0 App。
// required when local database does not exist or was deleted
public class ToDoContextFactory : IDesignTimeDbContextFactory<AppContext>
{
public AppContext CreateDbContext(string[] args)
{
var builder = new DbContextOptionsBuilder<AppContext>();
builder.UseSqlServer("Server=localhost;Database=DbName;Trusted_Connection=True;MultipleActiveResultSets=true");
return new AppContext(builder.Options);
}
}
当数据库不存在并且必须在运行更新数据库时创建时,这在 Core 2.0 中是必需的。
升级到 ASP.NET Core 2.0 后无法创建迁移
我不想在 2 个地方(这里和 appsettings.json 中)有 ConnectionString,但只在 .json 中,所以我尝试替换
"Server=localhost;Database=DbName;Trusted_Connection=True;MultipleActiveResultSets=true"
和
ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString
但它不起作用,我得到 null 值。
更新 1:
请注意,显式添加 .json 在 Core 2 中不是必需的,因此问题不在于文件。
https://andrewlock.net/exploring-program-and-startup-in-asp.net-core-2-preview1-2/
更新 2:
此外,我已经在使用 Configuration 将 ConnectionString 从 .json 发送到 Context:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
}
但是我不能将它用于ToDoContextFactory ,因为它没有配置,并且ToDoContextFactory被迁移使用,所以应用程序根本没有运行。
解决方案:根据@JRB 的回答,我让它像这样工作:
public AppContext CreateDbContext(string[] args)
{
string projectPath = AppDomain.CurrentDomain.BaseDirectory.Split(new String[] { @"bin\" }, StringSplitOptions.None)[0];
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(projectPath)
.AddJsonFile("appsettings.json")
.Build();
string connectionString = configuration.GetConnectionString("DefaultConnection");
var builder = new DbContextOptionsBuilder<AppContext>();
builder.UseSqlServer(connectionString);
return new AppContext(builder.Options);
}
第 1 步:在 OnConfiguring() 中包含以下内容
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
.AddJsonFile("appsettings.json")
.Build();
optionsBuilder.UseSqlServer(configuration.GetConnectionString("DefaultConnection"));
}
第 2 步:创建 appsettings.json:
{
"ConnectionStrings": {
"DefaultConnection": "Server=YOURSERVERNAME; Database=YOURDATABASENAME; Trusted_Connection=True; MultipleActiveResultSets=true"
}
}
第 3 步:将 appsettings.json 硬拷贝到正确的目录
Hard copy appsettings.json.config to the directory specified in the AppDomain.CurrentDomain.BaseDirectory directory.
Use your debugger to find out which directory that is.
假设:您已经在项目中包含了包 Microsoft.Extensions.Configuration.Json(从 Nuget 获取)。
在 ASPNET Core 中,您可以在Startup.cs
中执行此操作
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<BloggingContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("BloggingDatabase")));
}
您的连接在appsettings.json
中定义
{
"ConnectionStrings": {
"BloggingDatabase": "..."
},
}
来自MS 文档的示例
上面的解决方案和 Microsoft 文档中都缺少一些东西。 如果您按照从上述文档链接到 GitHub 存储库的链接,您会找到真正的解决方案。
我认为混淆在于许多人使用的默认模板不包含 Startup 的默认构造函数,因此人们不一定知道注入的 Configuration 来自哪里。
因此,在 Startup.cs 中,添加:
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
然后在 ConfigureServices 方法中添加其他人所说的话......
services.AddDbContext<ChromeContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DatabaseConnection")));
您还必须确保您已创建 appsettings.json 文件并具有与此类似的连接字符串部分
{
"ConnectionStrings": {
"DatabaseConnection": "Server=MyServer;Database=MyDatabase;Persist Security Info=True;User ID=SA;Password=PASSWORD;MultipleActiveResultSets=True;"
}
}
当然,您必须对其进行编辑以反映您的配置。
要记住的事情。 这是在 .Net Standard 2.1 项目中使用 Entity Framework Core 3 测试的。 我需要为以下各项添加 nuget 包:Microsoft.EntityFrameworkCore 3.0.0 Microsoft.EntityFrameworkCore.SqlServer 3.0.0,因为这是我正在使用的,并且是访问 UseSqlServer 所需的。
我知道这已被标记为已回答,但我在处理一个项目时遇到了一些问题,我的 .DLL 项目中的EF Core 数据访问层<\/strong>与我的项目的其余部分、API、Auth 和Web 和大多数人都会喜欢我的其他项目来引用这个 Data 项目。 而且我不想每次都进入 Data 项目来更改连接字符串。
第 1 步:将其包含在 OnConfiguring 方法中<\/strong>
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var envName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
IConfigurationRoot configuration = new ConfigurationBuilder()
**.SetBasePath(Path.Combine(Directory.GetCurrentDirectory()))**
.AddJsonFile("appsettings.json", optional: false)
.AddJsonFile($"appsettings.{envName}.json", optional: false)
.Build();
optionsBuilder.UseSqlServer(configuration.GetConnectionString("DefaultConnection"));
}
将它作为 dp 注入传递给该类怎么样? 在配置服务中:
services.Configure<MyOptions>(Configuration);
实际上,您可以使用默认模式来实现此结果,而无需实现
IDesignTimeDbContextFactory<\/code>并进行任何配置文件复制。
此文档<\/a>中对此进行了详细说明,其中还讨论了框架在设计时尝试实例化
DbContext<\/code>的其他方式。
具体来说,您利用了一个新的钩子,在本例中是一个形式为
public static IWebHost BuildWebHost(string[] args)<\/code>的静态方法。
文档另有说明,但此方法可以存在于包含您的入口点的任何类中( 请参阅 src<\/a> )。
实现这一点是
1.x 到 2.x 迁移文档<\/a>中指南的一部分,从代码中看并不完全明显的是,对
WebHost.CreateDefaultBuilder(args)<\/code>的调用是在默认情况下连接您的配置新项目开始的模式。
这就是让设计时服务(如迁移)使用的配置所需的全部内容。
这里有更多关于那里发生的事情的详细信息:
在添加迁移时,当框架尝试创建
DbContext<\/code>时,它
最后,它在程序集中
查找<\/a>任何
DbContext<\/code>派生类,并创建一个工厂方法,该方法只调用
Activator.CreateInstance<\/code>作为最终的 hail mary。
框架使用的优先顺序与上述相同。 因此,如果您实现了
IDesignTimeDbContextFactory<\/code> ,它将覆盖上面提到的钩子。
不过,对于最常见的场景,您不需要
IDesignTimeDbContextFactory<\/code> 。
您也可以在 ASP.NET Core 2 中通过在appSettings.json
文件中定义连接字符串来执行此操作。 然后在Startup.cs
中指定要使用的连接字符串。
appSettings.json
{
"connectionStrings": {
"YourDBConnectionString": "Server=(localdb)\\mssqllocaldb;Database=YourDB;Trusted_Connection=True"
}
}
Startup.cs
public static IConfiguration Configuration { get; private set;}
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
var connectionString = Configuration["connectionStrings:YourDBConnectionString"];
services.AddDbContext<YourDbContext>(x => x.UseSqlServer(connectionString));
将以下代码添加到
startup.cs<\/code>文件中。
在Context<\/code>类中使用GlobalProperties.DBConnection<\/code>属性。
我知道这并不奇怪,但您可以使用回调类,创建主机构建器并将配置设置为静态属性。
对于 asp 核心 2.2:
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using System;
namespace Project
{
sealed class Program
{
#region Variables
/// <summary>
/// Last loaded configuration
/// </summary>
private static IConfiguration _Configuration;
#endregion
#region Properties
/// <summary>
/// Default application configuration
/// </summary>
internal static IConfiguration Configuration
{
get
{
// None configuration yet?
if (Program._Configuration == null)
{
// Create the builder using a callback class
IWebHostBuilder builder = WebHost.CreateDefaultBuilder().UseStartup<CallBackConfiguration>();
// Build everything but do not initialize it
builder.Build();
}
// Current configuration
return Program._Configuration;
}
// Update configuration
set => Program._Configuration = value;
}
#endregion
#region Public
/// <summary>
/// Start the webapp
/// </summary>
public static void Main(string[] args)
{
// Create the builder using the default Startup class
IWebHostBuilder builder = WebHost.CreateDefaultBuilder(args).UseStartup<Startup>();
// Build everything and run it
using (IWebHost host = builder.Build())
host.Run();
}
#endregion
#region CallBackConfiguration
/// <summary>
/// Aux class to callback configuration
/// </summary>
private class CallBackConfiguration
{
/// <summary>
/// Callback with configuration
/// </summary>
public CallBackConfiguration(IConfiguration configuration)
{
// Update the last configuration
Program.Configuration = configuration;
}
/// <summary>
/// Do nothing, just for compatibility
/// </summary>
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//
}
}
#endregion
}
}
如果您需要不同的图层:
创建一个静态类并公开该层上的所有配置属性,如下所示:
只需使用
string connectionString =
builder.Configuration.GetConnectionString("TestDBConnectionString");
如果您使用的是“顶级语句”,则可以按如下方式获取连接字符串:
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
var builder = WebApplication.CreateBuilder();
string conStr = builder.Configuration.GetConnectionString("myDb1");
SqlConnection conn = new SqlConnection(conStr);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.