使用依赖项注入时,使用存储库模式的多DB上下文与UnitofWork



我正在开发一个包含多个模块的应用程序。我为同一数据库中不同模式下的不同模块创建了表,并在默认模式中创建了所有与用户相关的表。在阅读了更多关于dbcontext、工作单元和存储库模式的内容后,我感到更加困惑。我开始创建一个dbcontext,并意识到登录用户只需要少量的表,但通过调用构造函数,它将所有内容都带入内存。后来我考虑创建多个数据库上下文,但我必须在所有数据库上下文中包含与用户相关的表。

作为第三种选择,我开始使用工作单元和存储库模式。许多文章都说,这只是EF之上的另一个抽象,使用DBContext和DBSet。我仍在继续工作,并意识到我将拥有数百个存储库,一旦我将所有存储库添加到工作单元并调用构造函数,所有存储库都将再次加载到内存中。我完全不知道哪种方法最适合我的需要。每个控制器只需要特定的表存储库和用户表存储库来进行CRUD操作,但通过执行上述步骤,会不会导致性能问题?

我的工作单位如下

using DemoApp.Core;
using DemoApp.Core.Repositories;
using DemoApp.Persistence.Repositories;
namespace DemoApp.Persistence
{
public class UnitOfWork : IUnitOfWork
{
private readonly DemoAppContext _context;
public UnitOfWork(DemoAppContext context)
{
_context = context;
Ones = new OneRepository(_context);
Twos = new TwoRepository(_context);
}
public IOneRepository Ones { get; private set; }
public ITwoRepository Twos { get; private set; }
public int Complete()
{
return _context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
}
}

和控制器

using DemoApp.Core;
using DemoApp.Core.Domain;
using DemoApp.Persistence;
using System;
using System.Linq;
using System.Web.Mvc;
namespace DemoApp.Controllers
{
public class HomeController : Controller
{
private readonly IUnitOfWork _unitOfWork;
public HomeController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public ActionResult Index()
{
var result = _unitOfWork.Ones.GetAll();
return View(result);
}
}
}

有一个单独的大型上下文不会在构造时将实体加载到内存中,但它会解析实体映射,在非常大的上下文中,第一次加载可能需要几秒钟的时间。有边界的上下文适合非常大的系统,在这些系统中,您可以分离相关的实体,或者将"重"或时间敏感的实体与主要使用上下文分开。

我使用了一个具有有界上下文的模式,该模式使用对所讨论的上下文类型化的属性来标记哪些实体类型配置应用于什么上下文。这样可以使用较小的、只读的、适合的实体定义。不过,我只建议非常大的实体集使用此功能。通过使用延迟执行和.Select()表达式在需要时提取所需的数据,通常不需要使用多个有界实体声明。

使用工作单元&存储库模式主要围绕启用单元测试。我不建议使用Generic存储库(每个实体的存储库),而是像使用Controller模式一样使用repository模式。每个存储库为应用程序的一个区域提供检索、创建和删除与该区域相关的实体的方法。将一个存储库绑定到一个实体会导致大量的锅炉板代码,或者不平等地应用于所有实体的通用操作。它降低了代码的灵活性,最终使代码更难阅读。在大多数情况下,您应该利用实体之间映射的关系,因此单个存储库可以管理检索并对特定屏幕的所有相关实体采取行动,而不是在许多不同的存储库之间切换以尝试加载相关数据。我使用Mehdime的DbContextScope UoW模式,因为它方便了存储库/助手之间的读/写和只读作用域,并消除了向存储库中注入dbcontext/UoW包装器的需要。这使得在一个请求中具有多个UoW作用域,而不是将DbContext/UoW实例作用域确定为一个请求,或者如果您的容器支持,则手动处理生存期作用域。在任何情况下,它都值得一看作为一个选择。Mehdame的实现是针对EF 6.x的,而EF Core也有可用的fork。

最新更新