当 dbContext 也作为服务注入时如何使用连接字符串设置它
How to set dbContext with a connection string when it is also injected as a service
我在 web-api 项目中使用 EF-Core,并使用 DI 机制将 DBContext 注入操作方法。
但是 - 另外 - 我想在服务器启动时使用 EF dbContext 访问数据库, 在启动方法中 - 这是非 http 上下文,意思是 - DBContext 尚未启动 - 它在 ConfigureServices 方法中启动,并且在 stratup 方法之后启动.
为了进一步解释,这是 Startup.cs 和相关流程的其余部分:
public class Startup
{
public IConfiguration Configuration {get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
RepositoriesManager.Initiate(configuration);
//In addition - I now would like to use it to initiate repository by using the EF Core dbContext
//Another option is to run this methos after adding the dbContext serice - in the ConfigureServices
}
public void ConfigureServices(IServiceCollection services)
{
services.Add....
services.AddDbContext<MyDBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("myDB)));
//Option to execute it here instead of in the Startup
RepositoriesManager.Initiate(configuration);
}
}
RepositoriesManager
是一个静态 class ,使用配置从外部获取数据 API
public static Class RepositoriesManager
{
static RepositoriesManager(){} //static constructor
public static void Initiate(IConfiguration configuration)
{
//to make a long story short:
GetDataFromDBUsingEF();
}
//This method can be called also from action method (controller) - where the myDBContext is passed - this is not the case here
public static GetDataFromDBUsingEF(MyDBContext myDBContext = null)
{
if (myDBContext == null)
{
//one option - not working:
var serviceCollection = new Microsoft.Extensions.DependencyInjection.ServiceCollection();
var sp = serviceCollection.GetService<MyDBContext>();
//second option - also not working:
myDBContext = new MyDBContext(); // This should initiate the DBContext in some scenarios
}
}
}
我正在尝试使用 dbContext OnConfiguration 方法:
protected override void OnConfiguration(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
IConfigurationRoot configuration = new ConfigurationBuilder().SetBasePath(AppDomain.CurrentDomain.BaseDirectory).AddJsonFile("appsettings.json").Build();
optionsBuilder.UseSqqlServer(configuration.GetConnectionString("<connection string key>"));
}
}
在每次 DbContext 启动时都应使用其构造函数调用此方法。
现在当我启动 dbContext 时还没有达到它。我认为原因是文档所声称的:
“如果在此上下文的选项上明确设置模型(通过 Microsoft.EntityFrameworkCore.DbContextOptionsBuilder.UseModel(Microsoft.EntityFrameworkCore.Metadata.IModel)),则此方法将不会 运行” .
如何在未注入时获取 DBContext?
选项 1:通过 new
在启动构造函数中获取上下文
public Startup(IConfiguration configuration)
{
Configuration = configuration;
var contextOptions = new DbContextOptionsBuilder<MvcContext>()
.UseSqlServer(Configuration.GetConnectionString("MvcContext"))
.Options;
using var context = new MvcContext(contextOptions);
var configFromDb = context.MvcConfiguration.First();
}
选项 2:在 ConfigureServices
中调用 Configure
所需的选项并使用上下文(将在实际使用选项时调用)
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDbContext<MvcContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("MvcContext"));
});
services.AddOptions<DbConfigOptions>().Configure<IServiceProvider>((options, sp) =>
{
using var scope = sp.CreateScope();
using var dbContext = scope.ServiceProvider.GetRequiredService<MvcContext>();
options.UseDeveloperExceptionPage = dbContext.MvcConfiguration.Single().UseDeveloperExceptionPage;
});
}
选项3:当DBContext
配置在ConfigureServices
中时,可以在Startup.Configure
中注入使用
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, MvcContext dbContext)
{
var configFromDb = dbContext.MvcConfiguration.Single();
//...
}
我在 web-api 项目中使用 EF-Core,并使用 DI 机制将 DBContext 注入操作方法。 但是 - 另外 - 我想在服务器启动时使用 EF dbContext 访问数据库, 在启动方法中 - 这是非 http 上下文,意思是 - DBContext 尚未启动 - 它在 ConfigureServices 方法中启动,并且在 stratup 方法之后启动. 为了进一步解释,这是 Startup.cs 和相关流程的其余部分:
public class Startup
{
public IConfiguration Configuration {get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
RepositoriesManager.Initiate(configuration);
//In addition - I now would like to use it to initiate repository by using the EF Core dbContext
//Another option is to run this methos after adding the dbContext serice - in the ConfigureServices
}
public void ConfigureServices(IServiceCollection services)
{
services.Add....
services.AddDbContext<MyDBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("myDB)));
//Option to execute it here instead of in the Startup
RepositoriesManager.Initiate(configuration);
}
}
RepositoriesManager
是一个静态 class ,使用配置从外部获取数据 API
public static Class RepositoriesManager
{
static RepositoriesManager(){} //static constructor
public static void Initiate(IConfiguration configuration)
{
//to make a long story short:
GetDataFromDBUsingEF();
}
//This method can be called also from action method (controller) - where the myDBContext is passed - this is not the case here
public static GetDataFromDBUsingEF(MyDBContext myDBContext = null)
{
if (myDBContext == null)
{
//one option - not working:
var serviceCollection = new Microsoft.Extensions.DependencyInjection.ServiceCollection();
var sp = serviceCollection.GetService<MyDBContext>();
//second option - also not working:
myDBContext = new MyDBContext(); // This should initiate the DBContext in some scenarios
}
}
}
我正在尝试使用 dbContext OnConfiguration 方法:
protected override void OnConfiguration(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
IConfigurationRoot configuration = new ConfigurationBuilder().SetBasePath(AppDomain.CurrentDomain.BaseDirectory).AddJsonFile("appsettings.json").Build();
optionsBuilder.UseSqqlServer(configuration.GetConnectionString("<connection string key>"));
}
}
在每次 DbContext 启动时都应使用其构造函数调用此方法。 现在当我启动 dbContext 时还没有达到它。我认为原因是文档所声称的: “如果在此上下文的选项上明确设置模型(通过 Microsoft.EntityFrameworkCore.DbContextOptionsBuilder.UseModel(Microsoft.EntityFrameworkCore.Metadata.IModel)),则此方法将不会 运行” .
如何在未注入时获取 DBContext?
选项 1:通过 new
public Startup(IConfiguration configuration)
{
Configuration = configuration;
var contextOptions = new DbContextOptionsBuilder<MvcContext>()
.UseSqlServer(Configuration.GetConnectionString("MvcContext"))
.Options;
using var context = new MvcContext(contextOptions);
var configFromDb = context.MvcConfiguration.First();
}
选项 2:在 ConfigureServices
中调用 Configure
所需的选项并使用上下文(将在实际使用选项时调用)
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDbContext<MvcContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("MvcContext"));
});
services.AddOptions<DbConfigOptions>().Configure<IServiceProvider>((options, sp) =>
{
using var scope = sp.CreateScope();
using var dbContext = scope.ServiceProvider.GetRequiredService<MvcContext>();
options.UseDeveloperExceptionPage = dbContext.MvcConfiguration.Single().UseDeveloperExceptionPage;
});
}
选项3:当DBContext
配置在ConfigureServices
中时,可以在Startup.Configure
中注入使用
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, MvcContext dbContext)
{
var configFromDb = dbContext.MvcConfiguration.Single();
//...
}