首页 > 解决方案 > .Net 5 在控制器中更改 DbContext

问题描述

我有一个设计,其中有一个“主”数据库和多个“客户端”数据库。当我收到请求时,我会在主数据库中查找并设置与正确客户端数据库的连接。

我现在正在尝试在 .net 5 中进行相同的设计,在 StartUps ConfigureServices() 中设置 masterDB:

services.AddDbContext<Models.DataContext.MasterContext>(options => 
options.UseSqlServer("Name=MasterDB"));

然后我在 MasterDB 中的请求查找作为每个控制器方法中的第一件事,并找到 clientDB 的连接字符串。

但是我该如何在那个时间点进行设置呢?虽然也不必考虑处理连接,例如当它使用依赖注入传入时,它已被处理。

也鼓励任何建议做一些稍微不同的事情。

标签: entity-frameworkasp.net-core

解决方案


将您的 MasterContext 注入为您的“客户端”数据库(可能带有缓存)提供连接字符串查找的服务中。然后在解析和配置“客户端”DbContext 时使用它。

像这样的东西:

    class ClientDatabaseService
    {
        MasterDbContext db;
        IHttpContextAccessor context;

        static Dictionary<string, string> cache = null;
        public ClientDatabaseService(MasterDbContext db, IHttpContextAccessor context)
        {
            this.db = db;
            this.context = context;
            if (cache == null) RefreshCache();
        }
        public void RefreshCache()
        {
            cache = db.Clients.Select(c => new { c.ClientID, c.ConnectionString }).ToDictionary(c => c.ClientID, c => c.ConnectionString);
        }
        public string GetClientConnectionString()
        {
            var clientId = context.HttpContext.User.FindFirst("ClientID").Value;
            
            return cache[clientId];
        }

    }
    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();

        services.AddDbContext<MasterDbContext>();
        services.AddHttpContextAccessor();
        services.AddScoped<ClientDatabaseService>();

        services.AddDbContext<ClientDbContext>((services, options) =>
        {
            var constrService = services.GetRequiredService<ClientDatabaseService>();
            var constr = constrService.GetClientConnectionString();
            options.UseSqlServer(constr, o => o.UseRelationalNulls());

        });


    }

推荐阅读