gpt4 book ai didi

c# - .net Core 2、EF 和 Multi-Tenancy - 基于用户的 Dbcontext 切换

转载 作者:行者123 更新时间:2023-12-03 15:09:51 25 4
gpt4 key购买 nike

我有(几乎)最糟糕的 Multi-Tenancy 。我正在构建一个 asp.net 核心网站,我正在将一堆 pokey 小 Intranet 网站移植到该网站。每个子站点将是一个 asp.net 区域。我有一个 IdentityContext对于身份的东西。我有多个供应商数据库副本,每个都有多个租户。 ApplicationUser类有一个我想用来切换数据库上下文的 OrgCode 属性。
我可以看到自己需要将 User.OrgCode 和 Area 映射到连接字符串的东西
Stack Overflow 上有很多这样的部分示例。经过一个下午的阅读,我很困惑。它的核心似乎是:

  • 从构造函数 args 中删除 DI dbcontext ref。
  • 在 Controller 构造函数中实例化 dbcontext。
  • 像以前一样使用 dbcontext。

  • 我在正确的轨道上吗?
    有没有连贯的例子?

    编辑 2020/07/09
    不幸的是,这变得更加紧迫。
    身份数据库与租户无关。 Identity 中的每个用户都有一个 OrgCode 标识符。 (自定义用户属性)。
    通过使用“成本中心”,每台服务器都内置了 Multi-Tenancy 。该服务器在每台服务器上都有一组名称相同的数据库。
  • 核心供应商数据库
  • 我们存储扩展的自定义数据库
  • 我们的工作输出的日志数据库

  • 还有一些特定于应用程序的小型数据库已经使用组织代码来识别用户
    服务器 A - 1 个组织代码
    服务器 B - 4 个组织代码
    服务器 C - 3 个组织代码参与项目,50+ 还没有(大部分是小)
    服务器 D - 目前未使用任何组织代码。服务器上80+。 (很快)
    不可能将所有组织合并到一台服务器上。存在法律和技术后果。每台服务器都有数百个远程转发器向它们报告需要更新的信息。这些提供的数据是我们的自定义作业使用的。
    梦想是继续在每个页面中使用 DI,并根据需要传递上下文。然后,上下文将足够聪明,可以根据用户名的 OrgCode 选择正确的底层连接详细信息。
    我犹豫要不要使用代理这个词,因为它在这个空间中似乎负载很重。
    hell ,如果我知道把它放在哪里,即使使用 switch 语句也可以
    想要的效果来自 Org XYZ 的用户加载需要供应商数据库的页面,他们从 XYZ 映射到的服务器获取一个。
    编辑 2020/07/13
    为了整理引用,我将 OrgCode 和 Server 切换为 Enums。上下文继承如下
  • 数据库上下文
  • CustLogsContext
       public virtual ServerEnum Server 
    {
    get
    {
    return ServerEnum.None;
    }
    }

    DbSet (etc)
  • CustLogsServerAContext
         public override ServerEnum Server 
    {
    get
    {
    return ServerEnum.ServerA;
    }
    }
  • CustLogsServerBContext(等)
  • CustLogsServerCContext (等)
  • CustLogsServerDContext(等)

  • 供应商上下文
  • VendorServerAContext
  • VendorServerBContext (等)
  • VendorServerCContext (等)
  • VendorServerDContext (等)



  • 我还创建了一个静态类 OrgToServerMapping,其中包含一个将 OrgCodes 映射到服务器的字典。目前是硬编码的,最终会改为从配置加载,并添加一个重新加载方法。
    目前认为我需要一个收集上下文的类将有 Dictionary<serverEnum, dbcontext>并注册为服务。很确定我需要每个继承的 dbcontext 的对象版本,除非有人知道我可以使用的多态技巧

    最佳答案

    我在具有数千个数据库的类似系统上工作,但使用的是 LinqToSql 而不是 EF(我知道......)。希望一般的想法能转化。有connection pool fragmentation如果您最终拥有许多数据库,那么您必须应对的问题,但对于您的四个数据库,您不必担心这一点。
    我喜欢这两种方法 - 它们都假设您可以设置当前的 ApplicationUser通过DI注入(inject)。
    方法 #1:在 Startup 中,配置返回数据上下文的 DI 以获取当前用户,然后使用该用户构建正确的数据上下文。像这样的东西:

    // In Startup.ConfigureServices
    services.AddScoped<ApplicationUser>((serviceProvider) =>
    {
    // something to return the active user however you're normally doing it.
    });

    services.AddTransient<CustLogsContext>((serviceProvider) =>
    {
    ApplicationUser currentUser = serviceProvider.GetRequiredService<ApplicationUser>();

    // Use your OrgToServerMapping to create a data context
    // with the correct connection
    return CreateDataContextFromOrganization(currentUser.OrgCode);
    });
    方法 #2:与其直接注入(inject) CustLogsContext,不如注入(inject)一个依赖于负责构建数据上下文的事件用户的服务:
    // In Startup.ConfigureServices
    services.AddScoped<ApplicationUser>((serviceProvider) =>
    {
    // something to return the active user however you're normally doing it.
    });
    services.AddTransient<CustLogsContextWrapper>();

    // In its own file somewhere
    public class CustLogsContextWrapper
    {
    private ApplicationUser currentUser;
    public CustLogsContextWrapper(ApplicationUser currentUser)
    {
    this.currentUser = currentUser;
    }

    public CustLogsContext GetContext()
    {
    // use your OrgToServerMapping to create a data context with the correct connection;
    return CreateDataContextFromOrganization(user.OrgCode);
    }
    }
    我个人更喜欢后一种方法,因为它避免了在 Startup 中调用服务定位器,而且我喜欢封装数据上下文创建方式的细节。但是,如果我已经有一堆代码可以直接使用 DI 获取数据上下文,那么第一个就可以了。

    关于c# - .net Core 2、EF 和 Multi-Tenancy - 基于用户的 Dbcontext 切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60369553/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com