【问题标题】:Repository pattern with multiple databases具有多个数据库的存储库模式
【发布时间】:2019-09-22 07:19:30
【问题描述】:

我在 Windows 服务中使用 EF Core 和 Autofac 上的存储库模式。

我有一项服务需要连接几十个数据库,这些数据库具有相同的架构(相同的 dbcontext)但只有不同的数据。 如何使用 Autofac 在我的服务中实现这一点?贝洛

public class ReportRepository : IReportRepository
    {
        private readonly ReportDbContext dbContext;

        public ReportRepository(ReportDbContext dbContext)
        {
            this.dbContext = dbContext
        }

        public SomeModel GetData()
        {
            return dbContext.SalesData;
        }
    }

    public class ReportService : IReportService 
    {
        private readonly IReportRepository reportRepositoryEUServer;

        public ReportService(IReportRepository reportRepositoryEUServer)
        {
            this.reportRepositoryEUServer = reportRepositoryEUServer
        }

        public SomeModelDto GenerateReport()
        {
            var euData =  reportRepositoryEUServer.GetData();
            // I need to call other servers (e.g LATAM) here and get the data and aggregate them with euData
        }       
    }

【问题讨论】:

标签: c# .net .net-core entity-framework-core autofac


【解决方案1】:

创建基本上下文,包括所有设置、数据库集等:

public abstract class BaseContext : DbContext
{
    public BaseContext(DbContextOptions options)
    : base(options)
    { }
    public DbSet<object> FirstSet { get; set; }
    ...
}

BaseContext 继承两个数据库

public class LATAMContext : BaseContext
{
    public LATAMContext(DbContextOptions<LATAMContext> options) : base(options)
    {

    }
}

public class EUContext : BaseContext
{
    public EUContext(DbContextOptions<EUContext> options) : base(options)
    {

    }
}

并在Startup.cs注册两者

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<LATAMContext>(options => options.UseSqlServer(Configuration.GetConnectionString("LATAMConnectionString")));
    services.AddDbContext<EUContext>(options => options.UseSqlServer(Configuration.GetConnectionString("EUConnectionString")));

    // Autofac
    var builder = new ContainerBuilder();

    // needed only if you plan to inject ICollection<BaseContext>
    builder.RegisterType<LATAMContext>().As<BaseContext>();
    builder.RegisterType<EUContext>().As<BaseContext>();

    builder.Populate(services);


    return new AutofacServiceProvider(builder.Build());
}

appsettings.json中添加连接字符串

"ConnectionStrings": {
  "LATAMConnectionString": "Server=(localdb)\\mssqllocaldb;Database=ContosoUniversity1;Trusted_Connection=True;MultipleActiveResultSets=true",
  "EUConnectionString": "Server=(localdb)\\mssqllocaldb;Database=ContosoUniversity1;Trusted_Connection=True;MultipleActiveResultSets=true"
}

现在你可以注入两个上下文

public class ReportRepository : IReportRepository
{
    private readonly LATAMContext latamDbContext;
    private readonly EUContext euDbContext;

    public ReportRepository(LATAMContext latamDbContext, EUContext euDbContext)
    {
        this.latamDbContext = latamDbContext;
        this.euDbContext = euDbContext;
    }
}

或者如果你打算注入上下文集合

public class ReportRepository : IReportRepository
{
    private readonly ICollection<BaseContext> dbContexts;

    public ReportRepository(ICollection<BaseContext> dbContexts)
    {
        this.dbContexts = dbContexts;
    }
}

访问特定上下文

var _euContext = dbContexts.FirstOrDefault(x => x is EUContext) as EUContext;
var _latamContext = dbContexts.FirstOrDefault(x => x is LATAMContext) as LATAMContext;

【讨论】:

  • 您的解决方案看起来不错,但这不是我想要的。我只是给出了两个连接的示例。我有几十个这样的,硬编码它们会一团糟。我会更新这个问题,因为我最初没有提到这一点是我的错误。
  • 检查一下:stackoverflow.com/questions/40836102/… 应该满足您的需求
  • @Greg 这是否适用于 Code First 实体框架数据库迁移?
  • @MbusoMkhize 您可以指定用于迁移的上下文--context MyDbContext
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多