.net-core - 创建适当的数据库上下文 .NET Core 3
问题描述
我正在尝试在 .NET Core 3 启动中显式创建数据库上下文
我知道我可以在 startup.cs ConfigureServices 中执行此操作,以将 dbcontext 注入控制器(工作正常):
String dbconn = Configuration["ConnectionStrings:VerseDBConnectionStringMSSQL"];
services.AddDbContext<VerseDBContext>(options => options.UseSqlServer(dbconn));
但我试图概括存储提供程序(并使所有存储读取器的控制器代码保持相同),因此它需要一个 IVerseStorageReader 接口,而不是数据库上下文(因为我可能想从内存或 xmlfile 等中读取)并在控制器中使用相同的代码,只需根据 appsettings 中的配置进行切换即可。其中一个 VerseStorageReaders 在构造函数中采用 db 上下文:
public class DBVerseReader : IVerseStorageReader
{
private VerseDBContext _dbContext;
public DBVerseReader(VerseDBContext dbContext)
{
_dbContext = dbContext;
}
...
}
我的问题是:我不太清楚明确创建数据库上下文的语法。我非常接近(我认为),但这不起作用:
String dbconn = Configuration["ConnectionStrings:VerseDBConnectionStringMySQL"];
var optionsBuilder = new DbContextOptionsBuilder<VerseDBContext>();
optionsBuilder.UseMySql(dbconn);
VerseDBContext x = optionsBuilder.UseMySql<VerseDBContext>(dbconn); <-- compile error
services.AddSingleton<IVerseStorageReader>(new DBVerseReader(x));
有人可以告诉我我做错了什么吗?我要注入的是 IVerseStorageReader 的一个实例,而不是 DBContext。VerseStorageReader 的重载将 db 上下文作为输入,而其他重载则采用其他输入(例如 xmlfilename 等)......所以我希望启动添加 IVerseStorageReaders 之一的实例并被注入(不是 dbcontext 注入)。
解决方案
配置后,您必须从构建器中获取选项
String dbconn = Configuration["ConnectionStrings:VerseDBConnectionStringMySQL"];
var optionsBuilder = new DbContextOptionsBuilder<VerseDBContext>();
optionsBuilder.UseMySql(dbconn);
DbContextOptions<VerseDBContext> options = optionsBuilder.Options;
VerseDBContext x = new VerseDBContext(options);
services.AddSingleton<IVerseStorageReader>(new DBVerseReader(x));
但是由于DbContext
派生类通常注册为作用域,我建议您将上下文移动到工厂委托中,并将服务抽象也注册为作用域。
String dbconn = Configuration["ConnectionStrings:VerseDBConnectionStringMySQL"];
var optionsBuilder = new DbContextOptionsBuilder<VerseDBContext>();
optionsBuilder.UseMySql(dbconn);
DbContextOptions<VerseDBContext> options = optionsBuilder.Options;
services.AddScoped<IVerseStorageReader>( sp => {
VerseDBContext x = new VerseDBContext(options);
return new DBVerseReader(x);
});
推荐阅读
- c# - 将“第一个”数组的值放入“第二个”的问题。C#
- python - 有没有更快的方法来屏蔽数组?
- listview - 我在 ListView 中设置项目后,ListView 中的项目消失 - Java
- swift - 如何指定 UITextField 以在 Swift 中显示/隐藏键盘
- ruby - attr_encrypted gem在rails 6中不起作用
- c# - 找不到名为“”的视图组件
- swift - 为什么会在 Collection 视图中多次调用 willResignActiveNotification?
- javascript - 在网页上循环显示 DOM 元素
- java - MapStruct - 找不到实现
- javascript - 在 mxGraph 中,如何自动将文本标签放在新的图形单元格上?