Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
509 views
in Technique[技术] by (71.8m points)

c# - 动态更改Asp.Net Core中的连接字符串(Dynamically change connection string in Asp.Net Core)

I want to change sql connection string in controller, not in ApplicationDbContext.

(我想在控制器中而不是在ApplicationDbContext中更改sql连接字符串。)

I'm using Asp.Net Core and Entity Framework Core.

(我正在使用Asp.Net Core和Entity Framework Core。)

For example:

(例如:)

public class MyController : Controller {
    private readonly ApplicationDbContext _dbContext
    public MyController(ApplicationDbContext dbContext)
    {
        _dbContext = dbContext;
    }
    private void ChangeConnectionString()
    {
    // So, what should be here?
    } }

How can I do this?

(我怎样才能做到这一点?)

  ask by Yurii N. translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This is enough if you want to choose a connection string per http request, based on the active http request's parameters.

(如果您要基于活动的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);
        });

Update

(更新资料)

A year or so later, my solution looks like bits and pieces from other answers here, so allow me to wrap it up for you.

(大约一年后,我的解决方案看起来像这里其他答案中的点点滴滴,请允许我为您总结一下。)

You could add a singleton of the HttpContextAccessor on your startup file:

(您可以在启动文件上添加HttpContextAccessor单例:)

services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddDbContext<ERPContext>();

This will resolve the injection on your context constructor:

(这将解决对上下文构造函数的注入:)

public class ERPContext : DbContext
{
    private readonly HttpContext _httpContext;

    public ERPContext(DbContextOptions<ERPContext> options, IHttpContextAccessor httpContextAccessor)
        : base(options)
    {
        _httpContext = httpContextAccessor?.HttpContext;
    }

    //..

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        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));
    }

    //..
}

And this will give you a clean way to access and extract a claim and decide your connection.

(这将为您提供一种干净的方法来访问和提取索赔并确定您的联系。)

Your implementation of RetrieveYourBeautifulClientConnection(clientClaim) should return a string like this:

(您的RetrieveYourBeautifulClientConnection(clientClaim)实现应返回如下字符串:)

@"Server=YOURSERVER;Database=YOURDATABASE;Trusted_Connection=True;ConnectRetryCount=0"

As @JamesWilkins stated on the comments, OnConfiguring() will be called for each instance of the context that is created.

(正如@JamesWilkins在评论中指出的那样,将为所创建的上下文的每个实例调用OnConfiguring()。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...