use*_*831 2 c# asp.net-core-mvc asp.net-core
我想从控制器配置连接字符串,但我没有找到任何函数来执行此操作。
我有:
public class tstController : Controller
{
private readonly contextTst _context;
public tstController(contextTst context)
{
_context = context;
_context.Database.**????**
}
}
Run Code Online (Sandbox Code Playgroud)
这是可能的?
多谢!
小智 7
鉴于您想要在构造函数中设置替代连接字符串这一事实,表明它是一个已知值。
要解决的问题是如何用DI来做到这一点。第一个提示是搭建上下文时生成的代码:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
//#warning To protect potentially sensitive information in your
// connection string, you should move it out of source code.
// See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
optionsBuilder.UseSqlServer("Server=.\\SQLEXPRESS;Database=MyDb;Trusted_Connection=True;");
}
}
Run Code Online (Sandbox Code Playgroud)
这意味着您可以使用默认配置 (optionsBuilder.IsConfigured),在启动时设置值。但也可以在构造上使用替代方案。
代码将如下所示:
public partial class MyContext : DbContext
{
private readonly string _connectionString;
public MyContext(DbContextOptions<MyContext> options)
: base(options)
{
}
public MyContext(IOptions<DbConnectionInfo> dbConnectionInfo)
{
_connectionString = dbConnectionInfo.Value.MyContext;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(_connectionString);
}
}
}
Run Code Online (Sandbox Code Playgroud)
辅助类如下所示:
public class DbConnectionInfo
{
public string MyContext { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
示例 appsettings.json:
"ConnectionStrings": {
"MyContext": "Server=.\\SQLEXPRESS;Database=MyDb;Trusted_Connection=True;"
},
Run Code Online (Sandbox Code Playgroud)
并在启动时注册两者:
services.Configure<DbConnectionInfo>(settings => configuration.GetSection("ConnectionStrings").Bind(settings));
services.AddScoped<MyContext>();
Run Code Online (Sandbox Code Playgroud)
如果您不想从配置中读取连接字符串,而是根据中间件(例如每个租户)设置它,那么您可以使用相同的方法。只需在构建上下文之前更新该值即可。
更新:
通过依赖注入,您不必自己构造对象,而是将注册的对象/服务作为参数传递。DI 将找出需要按什么顺序创建哪些对象。同样,对象在使用后将由 DI 进行处理。
控制器“知道”上下文的事实是因为 DI 自动将其添加为参数。上下文“知道”DbConnectionInfo 的事实是因为它已注册到 DI。
如果您想更改 DbConnectionInfo,则需要以正确的方式添加它。在你的情况下,你可以这样做:
// Added as part of the example
services.AddHttpContextAccessor();
// Replace registration with this line:
services.AddScoped<DbConnectionInfo>();
// Register the DbContext
services.AddScoped<MyContext>();
Run Code Online (Sandbox Code Playgroud)
该类的替代版本是:
public class DbConnectionInfo
{
public string MyContext { get; set; }
// Example injecting IHttpContextAccessor
// On creating this class DI will inject
// the HttpContextAccessor as parameter
public DbConnectionInfo(IHttpContextAccessor httpContextAccessor)
{
// Access the current request
var request = httpContextAccessor.HttpContext.Request;
// Access the current user (if authenticated)
var user = httpContextAccessor.HttpContext.User;
// Now you could get a value from a header, claim,
// querystring or path and use that to set the value:
MyContext = "";
}
}
Run Code Online (Sandbox Code Playgroud)
在 DbContext 中进行一个小更改,在这种情况下我们不使用 IOptions:
public partial class MyContext : DbContext
{
private readonly string _connectionString;
public MyContext(DbConnectionInfo dbConnectionInfo)
{
_connectionString = dbConnectionInfo.MyContext;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(_connectionString);
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,每个请求都会在创建 MyContext 之前设置该值。
| 归档时间: |
|
| 查看次数: |
14574 次 |
| 最近记录: |