我想在 Controller 中更改 sql 连接字符串,而不是在 ApplicationDbContext 中。我正在使用 Asp.Net Core 和 Entity Framework Core。
例如:
public class MyController : Controller {
private readonly ApplicationDbContext _dbContext
public MyController(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
}
private void ChangeConnectionString()
{
// So, what should be here?
} }
我该怎么做?
最佳答案
如果您想根据事件的 http 请求参数为每个 http 请求选择一个连接字符串,这就足够了。
using Microsoft.AspNetCore.Http;
//..
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddDbContext<ERPContext>((serviceProvider, options) =>
{
var httpContext = serviceProvider.GetService<IHttpContextAccessor>().HttpContext;
var httpRequest = httpContext.Request;
var connection = GetConnection(httpRequest);
options.UseSqlServer(connection);
});
更新
大约一年后,我的解决方案看起来与此处其他答案的点点滴滴相似,所以请允许我为您总结一下。
您可以在启动文件中添加 HttpContextAccessor 的单例:
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddDbContext<ERPContext>();
这将解决上下文构造函数中的注入(inject)问题:
public class ERPContext : DbContext
{
private readonly HttpContext _httpContext;
public ERPContext(DbContextOptions<ERPContext> options, IHttpContextAccessor httpContextAccessor = null)
: base(options)
{
_httpContext = httpContextAccessor?.HttpContext;
}
//..
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
var clientClaim = _httpContext?.User.Claims.Where(c => c.Type == ClaimTypes.GroupSid).Select(c => c.Value).SingleOrDefault();
if (clientClaim == null) clientClaim = "DEBUG"; // Let's say there is no http context, like when you update-database from PMC
optionsBuilder.UseSqlServer(RetrieveYourBeautifulClientConnection(clientClaim));
}
}
//..
}
这将为您提供一种简洁的方式来访问和提取声明并决定您的连接。
作为@JamesWilkins在评论中指出,将为创建的每个上下文实例调用 OnConfiguring()。
注意可选访问器和 !optionsBuilder.IsConfigured
。
您将需要它们来简化您将覆盖上下文配置的测试。
关于c# - 动态更改 Asp.Net Core 中的连接字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36816215/