-1

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:

  1. Created 3 POCO classes for models in the "Entities" folder:

enter image description here

  1. 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();
     }
    
  2. 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();            
         }
     }
    
  3. 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)
         {
         }
     }
    
  4. 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();
         }
    }
egeo
  • 171
  • 1
  • 19
  • I'd highly suggest you to read this answer: https://stackoverflow.com/questions/50457007/in-memory-database-doesnt-save-data/50457230#50457230 – Camilo Terevinto Sep 21 '20 at 15:37

2 Answers2

0
  1. Register your BookRepository in onfigure method like services.AddScoped<IRepository, BookRepository>();
  2. Let the framework inject BookRepository instance by constructor injection to your controller.
Vivek Bani
  • 3,703
  • 1
  • 9
  • 18
0

As a side note, keep in mind that DbContext already is a Unit-of-Work and DbSet already is a repository.

Unless you have good reasons to wrap them with your own pattern implementations, you can (and should in most cases) just use the implementations provided by EF Core directly.

lauxjpn
  • 4,749
  • 1
  • 20
  • 40