dotnet muli db context

时间:2017-08-09 14:03:48

标签: database .net-core

在我的任务(dotnet core,c#)中,有必要选择其中一个数据库,并根据查询进行某种操作。

根据microsoft docs,它看起来像:

public class db1 : DbContext, Idb
{
    public db1(DbContextOptions options) : base(options)
    {}
}

public class db2 : DbContext, Idb
{
    public db2(DbContextOptions options) : base(options)
    {}
}

在Startup.cs

services.AddDbContext<db1>(options =>
    options.UseSqlServer(Configuration.GetConnectionString("db1")));

services.AddDbContext<db2>(options =>
    options.UseSqlServer(Configuration.GetConnectionString("db2")));

这允许您在DI中注册并访问特定的数据库连接实例,但所有数据库都是硬编码的。这是一个糟糕的代码。如何通过数据库的ID在DI中进行注册并在控制器中通过此ID从DI服务中选择更好?

1 个答案:

答案 0 :(得分:0)

这不是很糟糕,因为您可以根据您的环境更改连接字符串,具有appsetings.json的不同版本(appsettings.dev.json,appsettings.release.json等等)

另一方面,您可以在控制器结构中使用这些上下文,即 ctor 1:

   public FirstController(db1 context)

ctor2:

  public SecondController(db2 context)

也许,ctor3:

 public ThirdController(db1 contextA, db2 contextB )

BUT:

a)考虑命名约定(Idb ?? db1 ??)

b)为什么你想拥有两个相同类型的存储库......哦!您是否尝试使用Generic存储库模式?然后你的答案就在这里:https://github.com/Arch/UnitOfWork(我正在使用它,而且我对结果和表现非常讨厌,我将在下面粘贴一个例子)

使用IUnitOfWork:

在您的控制器中:

     public YourController(IUnitOfWork unitOfWork)
      {
          try
          {
              _unitOfWork = unitOfWork;
              // seeding
              var ItemRepository = _unitOfWork.GetRepository<Item>();

//ETC...

在StartUp的ConfigureServices中,调用此方法:

 private void AddEntityFrameworkAndDbContext(IServiceCollection services)
 {
     services.AddEntityFrameworkSqlServer();
     var migrationsAssemblyName = typeof(YourContext).GetTypeInfo().Assembly.GetName().Name;
     services.AddDbContext<YourContext>(options =>
     {
         options.UseSqlServer(Your.ConnectionString.NoMAtterHowYouGetIt,
            sqlServerOptionsAction: sqlOptions =>
            {
                 sqlOptions.MigrationsAssembly(migrationsAssemblyName);
                 sqlOptions.EnableRetryOnFailure(maxRetryCount: 5, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
             }); // Man, this is for free, I spent days getting it to work
     },
     ServiceLifetime.Scoped  // Showing explicitly that the DbContext is shared across the HTTP request scope (graph of objects started in the HTTP request)
     ).AddUnitOfWork<YourContext>();
 }

在配置中尝试类似:

app.EnsurePopulated(app.ApplicationServices.GetRequiredService());

我希望它可以帮到你,