I created a project ASP.NET Core 3 MVC and I need to work with the database through the Entity Framework Core using the DataBase first approach. Now there are 2 databases: MSSQL and PostgreSQL. I need to implement the repository pattern in its simplest form. How do I do this?
Both databases have tables: dbo.Author (public.Author), dbo.Book (public.Book) and dic.BookType with corresponding foreign keys. Which database will be used should be specified in the "ConfigureServices" method (if possible). My goal is not to depend on a specific database.
What I've already done:
- Created 3 POCO classes for models in the "Entities" folder:
This is how I defined the repository interface:
public interface IRepository<T> where T : class { Task<List<T>> GetAll(); Task<T> GetById<TId>(TId id); void Add(T entity); void Update(T entity); void Delete(T entity); Task<int> SaveChanges(); }
Create "Repository.cs":
public abstract class Repository<TEntity> : IRepository<TEntity> where TEntity : class { private readonly DbContext _context; public Repository(DbContext context) { _context = context; } public async virtual Task<List<TEntity>> GetAll() { return await _context.Set<TEntity>().ToListAsync<TEntity>(); } public async virtual Task<TEntity> GetById<TId>(TId id) { return await _context.Set<TEntity>().FindAsync(id); } public virtual void Add(TEntity entity) { _context.Set<TEntity>().Add(entity); } public virtual void Update(TEntity entity) { _context.Update(entity); } public virtual void Delete(TEntity entity) { _context.Set<TEntity>().Remove(entity); } public async virtual Task<int> SaveChanges() { return await _context.SaveChangesAsync(); } }
Created a repository for each entity: (do you really need to create another one for PostgreSQL?)
public class BookRepository : Repository<Entities.Book> { public BookRepository(Microsoft.EntityFrameworkCore.DbContext context) : base(context) { } }
Added 2 connsection strings to "appsettings.json".
What should be my next steps to do the same for PostgreSQL and how to use it in the controller?
Update:
now it's clear how it works. But if I have 30-40 tables (repositories), then it is not very convenient to register all of them in DI.
public void ConfigureServices(IServiceCollection services)
{
/*
string connStr = Configuration.GetConnectionString("MSSQLConnection");
services.AddDbContext<Common.ApplicationContext>(options =>
options.UseSqlServer(connStr));
*/
string connStr = Configuration.GetConnectionString("PostgreSQLConnection");
services.AddDbContext<Common.ApplicationContext>(options =>
options.UseNpgsql(connStr));
services.AddControllersWithViews();
}
I added a class with context. I thought that different databases should have their own class, but now it's clear. Therefore, we had to create all the necessary repositories in the controller using the context:
public class HomeController : Controller
{
protected /*DbContext*/ Common.ApplicationContext _context;
public HomeController(Common.ApplicationContext context)
{
_context = context;
}
public async Task<IActionResult> Index()
{
var bookRepo = new Common.Repositories.BookRepository(_context);
var books = await bookRepo.GetAll();
// ...
return View();
}
}