Ral*_*ama 1 entity-framework asp.net-core-mvc azure-web-app-service asp.net-core
我正在使用 Azure .NET 核心 WebApp、MVC、实体框架,搭建在现有的外部 MS SQL 数据库中。
我在启动 ConfigureServices 中注册数据库,如下所示:
services.AddDbContext<MyDbContext>(options => options.UseSqlServer());
Run Code Online (Sandbox Code Playgroud)
只要我在 MyDbContext.cs OnConfiguring() 方法中设置连接字符串,它就可以正常工作:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=10.10.10.10;Database=MyDb;user id=username;password=password;");
}
Run Code Online (Sandbox Code Playgroud)
然后我可以简单地在控制器中说:
private readonly MyDbContext _context;
public HomeController()
{
_context = new MyDbContext();
}
public IActionResult Index()
{
var item = _context.TableName.FirstOrDefault(d => d.Id > 0);
}
Run Code Online (Sandbox Code Playgroud)
这工作正常 - 数据流入。
我的问题是我需要根据连接的主机名更改 SQL 连接字符串。因此,无论是在启动 ConfigureServices() 中,如果我可以建立正在使用的主机名,我都可以传递连接,或者在 DB 的 MyDbContext.cs 文件的 OnConfiguring() 方法中。
我只能从 httpcontext 获取主机名,据我所知,在启动时无法查询?
如果我尝试将其注入 context.cs DB 文件,如下所示:
public partial class MyDbContext : DbContext
{
private readonly IHttpContextAccessor _httpContextAccessor;
public MyDbContext()
{
}
public MyDbContext(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor; // For context/url
}
public MyDbContext(DbContextOptions<MyDbContext> options, IHttpContextAccessor httpContextAccessor)
: base(options)
{
_httpContextAccessor = httpContextAccessor; // For context/url
}
Run Code Online (Sandbox Code Playgroud)
然后启动 ConfigureServices 行 services.AddDbContext 无法传递 httpcontext(当时它不存在?)没有任何构造函数方法匹配 - 无论我如何尝试,我都无法将 IHttpContextAccessor httpContextAccessor 注入到 DB 上下文方法中!
services.AddDbContext<MyDbContext>(options => options.UseSqlServer("some-connection-string")); // Doesn't pass httpcontext
services.AddDbContext<MyDbContext>()); // Doesn't pass httpcontext
services.AddDbContext<MyDbContext>(is there way to pass it?);
Run Code Online (Sandbox Code Playgroud)
它似乎不像将它注入控制器那样工作,因为那里没有构造函数,所以工作正常......
关于如何找到主机名并在给定此设置的情况下更改 SQL 连接字符串的任何想法?
出于各种原因,这需要是多个域顺便使用的单个 WebApp。
经过一个不眠之夜,我醒来并决定简单地连接到我需要的所有(三个)数据库,然后决定在控制器中使用哪个上下文,因为我在那里有 httpcontext 来决定哪个主机正在连接。这并不理想,但这是一个低开销的 WebApp,所以我很高兴能像这样使用它。我想也许那里有/曾经有一个解决方案......
这是我一直用于多租户解决方案(客户拥有自己的数据库)的方法。
使用此构造函数签名创建上下文(不需要OnConfiguring):
public class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options)
: base(options) { }
}
Run Code Online (Sandbox Code Playgroud)
在您的 Startup 中,您需要注册您的上下文,我们现在可以添加一个解析器来获取正确的连接设置:
services.AddHttpContextAccessor();
services.AddDbContext<MyDbContext>();
// This registers DbContextOptions<MyDbContext> which will be called when a new
// instance of MyDbContext is created. You could set breakpoints in this method.
services.AddScoped(sp =>
{
var context = sp.GetRequiredService<IHttpContextAccessor>().HttpContext;
// your logic to determine connection string or EF provider
// ...
var builder = new DbContextOptionsBuilder<MyDbContext>();
builder.UseSqlServer("connection string");
return builder.Options;
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
512 次 |
| 最近记录: |