我在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不存在时,Core 2.0中需要进行迁移,并且必须在运行 update-database 时创建。 Unable to create migrations after upgrading to ASP.NET Core 2.0
我希望在2个地方(此处和appsettings.json中)没有ConnectionString,但仅限于.json 所以我试图替换
"Server=localhost;Database=DbName;Trusted_Connection=True;MultipleActiveResultSets=true"
与
ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString
但它不起作用,我得到空值。
更新1:
请注意,在Core 2中明确添加.json是不必要的,所以问题不在于文件
https://andrewlock.net/exploring-program-and-startup-in-asp-net-core-2-preview1-2/
更新2:
此外,我已经使用Configuration从.json发送ConnectionString到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);
}
答案 0 :(得分:47)
步骤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获取)。
答案 1 :(得分:4)
实际上有一种默认模式可用于实现此结果,而无需实现IDesignTimeDbContextFactory
并执行任何配置文件复制。
详见this doc,其中还讨论了框架在设计时尝试实例化DbContext
的其他方式。
具体来说,您利用了一个新的钩子,在本例中是一个public static IWebHost BuildWebHost(string[] args)
形式的静态方法。文档另有说明,但这种方法可以存在于您的入口点(see src)的任何一个类中。实现这一点是1.x to 2.x migration document中的指导的一部分,并且对代码的看法并不完全明显,对WebHost.CreateDefaultBuilder(args)
的调用除其他外,是以新项目开始的默认模式连接您的配置用。这就是让迁移等设计时服务使用配置所需的一切。
以下是有关内心深处正在发生的事情的详细信息:
在添加迁移时,当框架尝试创建您的DbContext
时,first会将它找到的任何IDesignTimeDbContextFactory
实现添加到可用于创建您的工厂方法的集合中上下文,然后它通过前面讨论的静态钩子获取配置的服务,looks获取使用DbContextOptions
注册的任何上下文类型(当您使用Startup.ConfigureServices
时,AddDbContext
中会出现这种情况或AddDbContextPool
)并添加这些工厂。最后,通过程序集looks为任何DbContext
派生类创建一个工厂方法,只调用Activator.CreateInstance
作为最后的冰雹玛丽。
框架使用的优先顺序与上面相同。因此,如果您实现了IDesignTimeDbContextFactory
,它将覆盖上面提到的钩子。但是,对于大多数常见方案,您不需要IDesignTimeDbContextFactory
。
答案 2 :(得分:4)
在ASPNET Core中,您可以在Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<BloggingContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("BloggingDatabase")));
}
您在appsettings.json
中定义的连接
{
"ConnectionStrings": {
"BloggingDatabase": "..."
},
}
来自MS docs
的示例答案 3 :(得分:3)
如何将它作为dp注入传递给该类? 在ConfigureServices中:
services.Configure<MyOptions>(Configuration);
创建类来保存json字符串:
public class MyOptions
{
public MyOptions()
{
}
public string Option1 { get; set; }
public string Option2 { get; set; }
}
将字符串添加到json文件:
"option1": "somestring",
"option2": "someothersecretstring"
在需要这些字符串的类中,以构造函数的形式传入:
public class SomeClass
{
private readonly MyOptions _options;
public SomeClass(IOptions<MyOptions> options)
{
_options = options.Value;
}
public void UseStrings()
{
var option1 = _options.Option1;
var option2 = _options.Option2;
//code
}
}
答案 4 :(得分:2)
以上解决方案和Microsoft文档中都缺少一些内容。如果您按照上述文档中的链接链接到GitHub存储库,则将找到真正的解决方案。
我认为造成混淆的是,许多人使用的默认模板没有 not 包含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所必需的。
答案 5 :(得分:0)
您也可以在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));
答案 6 :(得分:0)
将以下代码添加到startup.cs
文件中。
public void ConfigureServices(IServiceCollection services)
{
string con = Configuration.GetConnectionString("DBConnection");
services.AddMvc();
GlobalProperties.DBConnection = con;//DBConnection is a user defined static property of GlobalProperties class
}
在GlobalProperties.DBConnection
类中使用Context
属性。
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(GlobalProperties.DBConnection);
}
}
答案 7 :(得分:0)
我了解这已被标记为已回答,但是当我在一个项目中将自己的 EF核心数据访问层放在一个与.DLL项目分开的项目中时,我遇到了一个问题我项目的其余部分,API,Auth和Web以及大多数人都希望我的其他项目引用此Data项目。而且我不想每次都进入Data项目更改连接字符串。
步骤1:将其包含在OnConfiguring方法中
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"));
}
注意:.SetBasePath(Path.Combine(Directory.GetCurrentDirectory())) 由于ASP.NET CORE足够聪明,可以选择正确的文件,因此这将使将文件复制到目录的需求无效或无效。同样,假设选择了Prod环境文件,则在为发布或生产版本构建时,指定的环境也会选择正确的文件。
第2步:创建appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "Server=YOURSERVERNAME; Database=YOURDATABASENAME; Trusted_Connection=True; MultipleActiveResultSets=true"
}
}
请:参考:Microsoft.Extensions.Configuration
答案 8 :(得分:0)
我不太了解,但是您可以使用回调类,创建hostbuilder并将配置设置为静态属性。
对于asp core 2.2:
def itemGrabber(url):
items = driver.find_elements_by_class_name('product')
print(str(len(items)) + " items found on page.")
for i in items:
## name of product
t = i.find_element_by_class_name('product-description__title').text.replace("\xad", "")
## price
p = i.find_element_by_class_name('product-price').text
writer.writerow((t, p))
products = itemGrabber(url)
因此,现在您只需在需要的其他任何类上使用静态的 Program.Configuration 。
答案 9 :(得分:0)
如果您需要在其他层:
创建一个静态类,并在该层上公开所有配置属性,如下所示:
using Microsoft.Extensions.Configuration;
using System.IO;
namespace Core.DAL
{
public static class ConfigSettings
{
public static string conStr1 { get ; }
static ConfigSettings()
{
var configurationBuilder = new ConfigurationBuilder();
string path = Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json");
configurationBuilder.AddJsonFile(path, false);
conStr1 = configurationBuilder.Build().GetSection("ConnectionStrings:ConStr1").Value;
}
}
}