Подключите несколько баз данных к основному проекту .NET через Entity Framework Core - PullRequest
1 голос
/ 26 сентября 2019

Я пытаюсь создать базовое приложение .NET, которое подключается к нескольким базам данных, но использует один общий репозиторий, содержащий логику для всех операций CRUD.Каков наилучший способ достичь этого?

    public Repository(ApplicationDbContext dbContext)
    {
        _dbContext = dbContext;
        _set = _dbContext.Set<T>();
    }

Выше находится конструктор моего хранилища.Здесь я вставляю ApplicationDbContext.Я ищу способ сделать этот ApplicationDbContext универсальным, поэтому мне нужен только один репозиторий, в котором я могу вводить различные контексты для доступа к нескольким базам данных.По сути, я ищу что-то вроде этого:

public class Repository_1<T> where T:EntityBase
{
    public Repository_1(IDbContext dbContext)
    {

    }
}

Где я могу поменять dbContext и заменить его другим контекстом, который подключается к другой базе данных.

Ответы [ 2 ]

2 голосов
/ 26 сентября 2019

Создать базовый контекст и включить в него все настройки, DBSET:

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

наследовать от BaseContext для обеих БД (Базы данных):

public class NavaContext : BaseContext
{
    public NavaContext (DbContext<NavaContext> options) : base(options)
    {

    }
}

public class StackContext : BaseContext
{
    public StackContext(DbContext<StackContext> options) : base(options)
    {

    }
}

и зарегистрировать оба в Startup.cs:

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

    // Autofac
    var builder = new ContainerBuilder();

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

    builder.Populate(services);


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

добавить строки подключения в appsettings.json:

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

, и теперь вы можете ввести оба контекста:

public class ReportRepository : IReportRepository
{
    private readonly NavaContext latamDbContext;
    private readonly StackContext euDbContext;

    public ReportRepository(NavaContext latamDbContext, StackContext euDbContext)
    {
        this.latamDbContext = latamDbContext;
        this.euDbContext = euDbContext;
    }
}

или если вы планируете внедритьcollection контекстов:

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

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

для доступа к конкретному контексту:

var _stackContext= dbContexts.FirstOrDefault(x => x is StackContext) as StackContext;
var _navaContext= dbContexts.FirstOrDefault(x => x is NavaContext) as NavaContext;
1 голос
/ 27 сентября 2019

Вы можете установить два параметра для своего репозитория и добавить к ним ограничения, например, если ваш dbContext наследуется от DbContext

public class TestRepository<TContext, T> : ITestRepository<TContext,T> 
    where TContext : DbContext
    where T : BaseEntity
{

    private readonly TContext _context;
    private DbSet<T> entities;


    public TestRepository(TContext context)
    {
        _context = context;
        entities = context.Set<T>();
    }



    public List<T> GetAll()
    {

        return entities.AsNoTracking().ToList();
    }
}

ITestReposiroty:

public interface ITestRepository<TContext,T>
    where TContext : DbContext
    where T : BaseEntity
{       
    List<T> GetAll();
}

Startup.cs

services.AddScoped(typeof(ITestRepository<,>), typeof(TestRepository<,>));

Контроллер:

public class ProductsController : ControllerBase
{
    private readonly ITestRepository<ApplicationDbContext, Product> _repository;

    public TestRepoController(ITestRepository<ApplicationDbContext, Product> repository)
    {
        _repository = repository;
    }
    // GET api/products

    [HttpGet]
    public List<Product> Get()
    {
        return _repository.GetAll();
    }
}
...