Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 根据配置值确定连接字符串_C#_Entity Framework Core_Asp.net Core 2.0_Asp.net Core Webapi - Fatal编程技术网

C# 根据配置值确定连接字符串

C# 根据配置值确定连接字符串,c#,entity-framework-core,asp.net-core-2.0,asp.net-core-webapi,C#,Entity Framework Core,Asp.net Core 2.0,Asp.net Core Webapi,我使用.Net内核 我有一个场景,需要根据departmentId将连接字符串切换到具有相同模式的两个不同数据库 我有一个名为Department1的数据库,其中存放着较旧的记录,管理层的决定是通过更新Config数据库中的逗号分隔切换设置DepartmentToggle定期将各个部门的记录移动到Department2。基本上,我们的ETL团队将把记录移动到新的数据库中,并在完成后更新此设置。长期计划是将这些数据库记录移动到云上。这是做这件事的第一步 因此,如果切换设置DepartmentTog

我使用
.Net内核

我有一个场景,需要根据departmentId将连接字符串切换到具有相同模式的两个不同数据库

我有一个名为
Department1
的数据库,其中存放着较旧的记录,管理层的决定是通过更新
Config
数据库中的逗号分隔切换设置
DepartmentToggle
定期将各个部门的记录移动到
Department2
。基本上,我们的ETL团队将把记录移动到新的数据库中,并在完成后更新此设置。长期计划是将这些数据库记录移动到云上。这是做这件事的第一步

因此,如果切换设置
DepartmentToggle
具有值
“1,2,3”
,则表示部门1、2、3记录位于
Department2
中。因此,我必须首先从
config
数据库中读取
DepartmentToggle
config值,检查DepartmentId是否包含在切换中。如果是,DepartmentContext必须使用
Department2
connectionString。下面是我的上下文类:

public partial class DepartmentContext : DbContext
{
    // Required for DI container
    public DepartmentContext() { }
    // Required for unit testing
    public DepartmentContext(DbContextOptions options) : base(options) {}

    public virtual DbSet<Faculty> Faculties { get; set; }
    public virtual DbSet<Student> Students { get; set; }
    ......
    //More DbSets

    //connectionString to change based on the DepartmentId
    public static string ConnectionString { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            optionsBuilder.UseSqlServer(ConnectionString);
        }
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        //modelBuilder.Entity<Faculty>(entity => { });
    }
}
public分部类DepartmentContext:DbContext
{
//DI容器需要
公共部门上下文(){}
//需要进行单元测试
公共部门上下文(DbContextOptions选项):基本(选项){}
公共虚拟数据库集功能{get;set;}
公共虚拟数据库集学生{get;set;}
......
//更多数据库集
//根据部门ID更改的connectionString
公共静态字符串连接字符串{get;set;}
配置时受保护的覆盖无效(DBContextOptions Builder Options Builder)
{
如果(!optionBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(ConnectionString);
}
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
//实体(实体=>{});
}
}

有什么建议吗?

你可以用以下方法来做

public class DepartmentContext : DbContext
{
    public DepartmentContext(
        IDepartmentRequestContext deptRequestContext, 
        IConnectionSelector connSelector) 
    : base(connSelector.GetConnectionString(deptRequestContext.SelectedDepartament))
    {
    }
}
创建一个DepartmentRequestContext类,其作用域为终生注册(或PerRequest,具体取决于您的容器)。然后,您可以创建一个中间件或请求处理程序,它将根据从配置数据库加载的1,2,3设置SelectedDepartment值。由于SelectedDepartment位于作用域实例中,因此在创建期间,相同的值将在您的部门上下文中可用

然后,在ConnectionSelector中,您基本上会根据所选的部门读取IOptions并检索相应的连接字符串


整个解决方案基于这样一个事实,即应该在部门已知并缓存在中间件中之后创建DepartmentContext。

如果您想在我的回答中进一步澄清什么,请告诉我