在 EF 上下文中使用 appsettings.json 配置
Posted
技术标签:
【中文标题】在 EF 上下文中使用 appsettings.json 配置【英文标题】:Using appsettings.json configuration in EF Context 【发布时间】:2021-11-29 18:58:27 【问题描述】:我应该指出我是 .NET 的新手...
我有以下 appsettings.json 文件:
"Logging":
"LogLevel":
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
,
"ConnectionStrings":
"MyContext": "Host=localhost;Database=test;Username=user;Password=''"
在 MyContext.cs 文件中,我想从 appsettings.json 配置中读取连接字符串:
using Microsoft.EntityFrameworkCore;
using System;
using System.Configuration;
namespace My.Models
public partial class MyContext : DbContext
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
Console.WriteLine(ConfigurationManager.ConnectionStrings.Count);
if (!optionsBuilder.IsConfigured)
optionsBuilder.UseNpgsql(ConfigurationManager.ConnectionStrings["MyContext"].ConnectionString);
但是ConfigurationManager.ConnectionStrings["MyContext"].ConnectionString
为空,有什么想法吗?
我通过Configuration.GetConnectionString("MyContext")
在 Startup.cs 中成功使用了配置文件,但在这里我想从该配置中读取连接字符串以用于 ASP.NET 应用程序之外的情况(即在我想要执行的 EF 迁移中) using var db = new MyContext();
),但不知道为什么上面返回 null。
ConfigurationManager 没有从我的 appsettings.json 文件中读取数据吗?不知道如何判断,因为ConfigurationManager.ConnectionStrings.Count
返回 1,所以我很困惑。有什么明显的错误有人可以看到吗?
我正在使用 .NET Core 5 和 EF Core 版本 5
【问题讨论】:
如何运行迁移? @GuruStron dotnet ef 数据库更新 咆哮:如果 migrationBuilder 允许我获取刚刚插入的数据,我什至不需要这个...... 你有完整的复制品吗?运行dotnet ef database update
时,您可以添加启动项目,以便在运行迁移时使用。您还可以详细说明“migrationBuilder 允许我获取刚刚插入的数据”。 - 你想达到什么目标?
您使用的是哪种类型的项目?如果您使用的是 API 或 Worker,您可以使用依赖注入来创建您的 DbContext
,并且在这种情况下,您无需将与 IConfiguration
相关的任何内容带入您的 EF Core 上下文中还有任何理由特别是在 DBContext 创建期间读取?通常对带有 Startup.cs 的项目的建议是让 EFCore 为您注入 DBContext
,然后您可以在那里获取连接字符串并将其作为依赖注入的参数
【参考方案1】:
在ef core中定义连接字符串的常用方法是
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
optionsBuilder.UseNpgsql(@"Host=localhost;Database=test;Username=user;Password=password");
您可以手动访问 IConfiguration:
-
将此包安装到 ef 项目中
Microsoft.Extensions.Configuration
Microsoft.Extensions.Configuration.Json
-
构建 IConfiguration
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
.AddJsonFile("appsettings.json")
.Build();
optionsBuilder.UseNpgsql(configuration.GetConnectionString("DefaultConnection"));
如果你的 Ef 核心在一个特殊的项目中,你必须将 appsetings.json 复制到这个项目中
如果您在查找 appsetings 文件夹时遇到问题,您可以直接定义路径
// .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
.AddJsonFile(@"C:\....\appsettings.json")
【讨论】:
是的,不幸的是我认为这是使用配置文件的唯一方法......我正在研究创建秘密。 很好,即使这样也会报错:使用了命名的连接字符串,但在应用程序的配置中找不到名称“ConnectionStrings:MyContext”。请注意,仅在使用“IConfiguration”和服务提供者时才支持命名连接字符串,例如在典型的 ASP.NET Core 应用程序中。请参阅go.microsoft.com/fwlink/?linkid=850912 了解更多信息。我不明白 .NET 为何如此受欢迎...... 最后采用了这个解决方案,谢谢【参考方案2】:我假设您正在运行 API 或 Blazor/Razor 应用程序,因为您提到了 Startup.cs
文件:)
在这种情况下,建议 (official docs about this) 是使用 Entity Framework 自己的库在 Startup.ConfigureServices
中设置您的 MyContext
。在那里,您可以访问应用程序的 IConfiguration
中的 ConnectionStrings
以及允许您使用特定连接字符串注册 DbContext
的扩展方法。
它可能看起来像这样,只需将我对 Sqlite
的调用调整为您正在使用的任何数据库驱动程序:
public class Startup
Startup(IConfiguration configuration)
_configuration = configuration;
void ConfigureServices(IServiceCollection services)
// Other dependencies go here
string connString = _configuration.GetConnectionString("MyContext");
services.AddDbContext<MyContext>(opt => opt.UseSqlite(connString));
// Other dependencies, et cetera
这使您可以防止配置逻辑“泄漏”到您的“模型”命名空间中,因此您的MyContext
问题仅与数据的持久性有关,而不是访问系统文件和环境变量。
为了在控制器上使用 MyContext
的实例或由.NET 的依赖注入系统创建的任何其他东西,您需要做的就是在类的构造函数中请求它,比如:
public class MyAwesomeController : ControllerBase
private readonly MyContext _context;
// This tells .NET to inject an instance of MyContext into your controller
public MyAwesomeController(MyContext context)
_context = context ?? throw new ArgumentNullException();
// Now all you gotta do is actually use that instance - no matter where it's connecting to
[HttpGet]
public Task ListEverything() => _context.MySet.ToListAsync();
【讨论】:
谢谢,但我在应用程序本身中使用它没有问题,而是在应用程序和迁移中使用上下文。应用会读取配置,迁移不会。 很公平,那么您是从另一个项目运行迁移吗?这是 EFCore 的一个缺点——当你想把所有东西都放在一个地方时,它非常简单,但是当你分成不同的项目时,它会变得有点棘手。 IIRC,您需要在用于运行迁移的项目中创建某种“ContextBuilder”,以便从命令行(作为dotnet ef database update
和其他命令的参数)或从 AppSettings 读取 ConnectionString。很高兴之前的答案可以让您畅通无阻! :D以上是关于在 EF 上下文中使用 appsettings.json 配置的主要内容,如果未能解决你的问题,请参考以下文章