首页 > 解决方案 > 创建适当的数据库上下文 .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 注入)。

标签: .net-coredbcontext

解决方案


配置后,您必须从构建器中获取选项

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);
});

推荐阅读