问题描述
我创建了一个项目ASP.NET Core 3 MVC,我需要使用数据库优先方法通过Entity Framework Core处理数据库。现在有2个数据库:MSsql和Postgresql。我需要以最简单的形式实现存储库模式。我该怎么做?
两个数据库都有表:dbo.Author(public.Author),dbo.Book(public.Book)和dic.BookType以及相应的外键。应该在“ ConfigureServices”方法中指定将使用哪个数据库(如果可能)。我的目标不是依赖特定的数据库。
我已经完成的事情:
- 在“实体”文件夹中为模型创建了3个POCO类:
-
这是我定义存储库接口的方式:
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(); }
-
创建“ 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(); } }
-
为每个实体创建一个存储库:(您真的需要为Postgresql创建另一个存储库吗?)
public class BookRepository : Repository<Entities.Book> { public BookRepository(Microsoft.EntityFrameworkCore.DbContext context) : base(context) { } }
-
在“ 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();
}
}
解决方法
- 使用
BookRepository
之类的onfigure
方法注册services.AddScoped<IRepository,BookRepository>()
; - 让框架通过构造函数注入向控制器注入
BookRepository
实例。
请注意,DbContext
已经是一个工作单元,DbSet
已经是一个存储库。
除非有充分的理由将它们包装到自己的模式实现中,否则您可以(并且在大多数情况下)可以直接使用EF Core提供的实现。