如何将ASP.NET Core MVC中的存储库模式与Entity Framework Core一起使用?

问题描述

我创建了一个项目ASP.NET Core 3 MVC,我需要使用数据库优先方法通过Entity Framework Core处理数据库。现在有2个数据库:MSsql和Postgresql。我需要以最简单的形式实现存储库模式。我该怎么做?

两个数据库都有表:dbo.Author(public.Author),dbo.Book(public.Book)和dic.BookType以及相应的外键。应该在“ ConfigureServices”方法中指定将使用哪个数据库(如果可能)。我的目标不是依赖特定的数据库

我已经完成的事情:

  1. 在“实体”文件夹中为模型创建了3个POCO类:

enter image description here

  1. 这是我定义存储库接口的方式:

     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. 创建“ 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. 为每个实体创建一个存储库:(您真的需要为Postgresql创建另一个存储库吗?)

     public class BookRepository : Repository<Entities.Book>
     {
         public BookRepository(Microsoft.EntityFrameworkCore.DbContext context) : base(context)
         {
         }
     }
    
  4. 在“ appsettings.json”中添加了2个连接字符串。

对Postgresql进行相同操作的下一步是什么,以及如何在控制器中使用它?

更新

现在很清楚它是如何工作的。但是,如果我有30-40个表(存储库),那么在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();
    }

添加了带有上下文的类。我以为不同的数据库应该有自己的类,但是现在很清楚了。因此,我们必须使用上下文在控制器中创建所有必需的存储库:

    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();
         }
    }

解决方法

  1. 使用BookRepository之类的onfigure方法注册services.AddScoped<IRepository,BookRepository>()
  2. 让框架通过构造函数注入向控制器注入BookRepository实例。
,

请注意,DbContext已经是一个工作单元,DbSet已经是一个存储库。

除非有充分的理由将它们包装到自己的模式实现中,否则您可以(并且在大多数情况下)可以直接使用EF Core提供的实现。