通过DI将选定的数据库传递给DBcontext

时间:2018-08-29 12:37:26

标签: entity-framework-core asp.net-core-2.0

这是我的情况。想象一下一个屏幕,上面有美国各州的下拉菜单。此列表是从一个Admin数据库填充的。根据屏幕上其他项目的选择,填充其他数据库。我们每个州都有一个共享单个模式的数据库。使用“状态”下拉菜单中的DI,我没有任何问题。但是,我在获取选定状态时遇到问题。我测试了状态的硬编码,并且DI可以正常工作。我想为此使用Session,但是坦白地说,我读过你无法理解,我无法使其工作。任何建议,将不胜感激。

        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        services.AddScoped(p => p.GetService<IHttpContextAccessor>()?.HttpContext);


        services.AddDbContext<AdminManagement.Data.AdminDataContext>(options =>
            options.UseSqlServer(Configuration.GetSection("Connections:myAdmin").Value).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking));          

        //this is the issue here I want to be able to pass the selected state 
        services.AddDbContext<CollectionDataContext>((serviceProvider, builder) =>
        {
            //I wish I could use this...any alternatives?
            //HttpContext.Session.GetString("SelectedState");

            //hardcoded for testing purposes. it works ok 
            var selectedDb = "SC"; 

            //this gets the connection string from app settings, later I will get it from an API
            var connectionString = GetConnectionStringFromService(selectedDb);
            builder.UseSqlServer(connectionString);
        });

        //my one admin database Data context
        services.AddScoped<AdminManagement.Data.AdminManagementQueries>();

        // my multiple databases clases that use DI
        services.AddScoped<CollectionManagementQueries>();
        services.AddScoped<CollectionManagementCommands>();

1 个答案:

答案 0 :(得分:1)

您需要从服务提供商那里获取上下文。通过以下方式完成:

var httpContextAccessor = serviceProvider.GetRequiredService<IHttpContextAccessor>();

然后,您可以执行以下操作:

var selectedDb = httpContextAccessor.HttpContext.Session.GetString("SelectedState");

但是请注意,IHttpContextAccessor默认情况下未注册。您可以通过在ConfigureServices中添加以下内容来解决此问题:

services.AddHttpContextAccessor();