【问题标题】:Switch database using routes使用路由切换数据库
【发布时间】:2019-02-26 13:20:47
【问题描述】:

这是我的场景:

我有一个应用,但是我需要通过路由切换数据库连接。

例子:

switch(route)
{
    case(URL/A):
    { 
        USE DATABASE 1 
    }
    case(URL/B):
    { 
        USE DATABASE 2
    }
    DEFAULT:
        USE DATABASE DEFAULT
 }

有可能吗?

【问题讨论】:

  • 在您的代码 sn-p 中打开三个 { 但只有两个关闭 }
  • 简单的答案,是的,但有很多与此相关的陷阱。这两个实体是否相同?只是连接不同吗?
  • 是的,彼得,所有实体都是一样的,只是数据不同
  • Uwe Keim,这在开关盒中是正常的。
  • 彼得,我该怎么做?

标签: c# asp.net asp.net-mvc entity-framework


【解决方案1】:

由于您使用的是 ASP.NET MVC,因此您的路由取决于您的控制器。然后你可以想象让 ControllerA 使用 DatabaseA 和 ControllerB 使用 DatabaseB。

要使用多个数据库连接,您需要为每个数据库连接一个连接字符串。

我将使用以下代码片段在 Startup.ConfigureServices() 中注入 DbContextOptionsBuilder 的实例

var ContextAOptionsBuilder = new DbContextOptionsBuilder<ContextA>();
var ContextBOptionsBuilder = new DbContextOptionsBuilder<ContextB>();

然后您可以通过这种方式配置您的构建器(取决于您的参数)

ContextAOptionsBuilder.UseSqlServer(Configuration.GetConnectionString("ContextAConnectionString"), builder =>
        {
            builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(30), null);
        });
ContextAOptionsBuilder.EnableSensitiveDataLogging();

然后您可以通过这种方式将它们作为单例注入:

services.AddSingleton(typeof(DbContextOptionsBuilder<ContextA>),ContextAOptionsBuilder);

您可以使用 BaseController,其构造函数参数可以通过这种方式访问​​服务:

public BaseController(IConfiguration configuration, IMemoryCache memoryCache,
        IHttpContextAccessor contextAccessor,
        DbContextOptionsBuilder<ContextA> ContextAOptionsBuilder,
        DbContextOptionsBuilder<ContextB> ContextBOptionsBuilder){}

当然,ControllerA 和 ControllerB 是 BaseController 的继承类,您可以非常简单地访问所需的构建器。

  public ControllerA(IConfiguration configuration,
                     IMemoryCache cache, 
                     IHttpContextAccessor contextAccessor, 
                     DbContextOptionsBuilder<ContextA> ContextAOptionsBuilder,
                     DbContextOptionsBuilder<ContextB> ContextBOptionsBuilder)
    :base(configuration, cache, contextAccessor, ContextAOptionsBuilder,ContextBOptionsBuilder)
    { 
         //Create your DbContext using the builder
    }

这样您可以使用一个、另一个或两个数据库来构建您的上下文

一种更简单的方法是注入您的配置文件并根据其内容构建您的上下文,但 ppumkin 的评论建议在控制器级别执行此操作是一个坏主意。

此解决方案在 ASP.NET Core MVC 应用程序中为我工作,我仍在学习该框架,但也许我的回答为您提供了有关多个 DbContexts 的精确度。

【讨论】:

    【解决方案2】:

    您可以创建 3 个连接字符串也可以创建 3 个数据访问类。您的类的第一个使用例如 DropCreateDatabaseIfModelChanges 其他使用 CreateDatabaseIfNotExists。当您调用第一类时,您的数据库在您需要其他人时创建,则无需重新创建它。

    【讨论】:

    • 在存储库上下文中。请不要在控制器级别执行此操作。创建一个可以接受不同配置并且可以通过 DI 轻松交换的存储库
    【解决方案3】:

    注册您的上下文(作为范围,每个请求)并使用工厂方法根据当前路由(应该可以从HttpContext 或类似的东西获得)使用指定的连接字符串动态创建上下文。如果数据库模式相同并且只是数据不同,这应该很容易工作。我无法为您提供 sn-p,因为它主要取决于您拥有的 DI 框架。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 2020-10-26
      • 2016-05-26
      • 1970-01-01
      • 2014-07-11
      • 2021-03-09
      • 1970-01-01
      相关资源
      最近更新 更多