我已阅读了大量文章,我认为这就是我的应用程序应该如何
实体框架 – >存储库 – >工作单位 – >客户端(Asp MVC)
我附上了本文中的一些代码
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
using System; using ContosoUniversity.Models; namespace ContosoUniversity.DAL { public class UnitOfWork : IDisposable { private SchoolContext context = new SchoolContext(); private GenericRepository<Department> departmentRepository; private GenericRepository<Course> courseRepository; public GenericRepository<Department> DepartmentRepository { get { if (this.departmentRepository == null) { this.departmentRepository = new GenericRepository<Department>(context); } return departmentRepository; } } public GenericRepository<Course> CourseRepository { get { if (this.courseRepository == null) { this.courseRepository = new GenericRepository<Course>(context); } return courseRepository; } } public void Save() { context.SaveChanges(); } private bool disposed = false; protected virtual void Dispose(bool disposing) { if (!this.disposed) { if (disposing) { context.Dispose(); } } this.disposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } } }
工作单元将具有存储库,并将在创建时创建DBContext
因此,控制器将在创建时创建工作单元.
要显示数据,我将使用此代码
var department = UoW.departmentRepository.Find(1); return View(department);
当客户端单击“保存”按钮时,我将运行此代码
UoW.departmentRepository.Update(department); UoW.Save();
我的问题:
>如果从数据检索到客户端单击保存按钮需要数小时,该怎么办?据我所知,我们必须尽量缩短背景.
>我应该把业务逻辑放在哪里?我把它放在存储库中吗?所以我会在保存之前调用UoW.departmentRepository.Validate(部门).但是,如果我需要验证与其他实体相关的实体,该怎么办?我是否打电话给UoW.departmentRepository.Validate(课程,部门)?
是否有针对此类应用的完整示例项目?
编辑
正如Ant P所建议的那样,我需要添加另一层来实现我的业务逻辑.
这就是我到目前为止所得到的
工作单位:
public class UnitOfWork : IDisposable { private DBContext _context = new DBContext(); public DBContext Context { get { return this._context; } } public void Save() { _context.SaveChanges(); } private bool disposed = false; protected virtual void Dispose(bool disposing) { if (!this.disposed) { if (disposing) { context.Dispose(); } } this.disposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } }
商业逻辑:
public class SalesBusinessLogic : IDisposable { private ICustomerRepository _customerRepo; private ISalesRepository _salesRepo; private UnitOfWork _uow; public SalesBusinessLogic(UnitOfWork uow) { this._uow = uow; } public ICustomerRepository CustomerRepo { get { if (this._customerRepo == null) { this._customerRepo = new CustomerRepository(this._uow); } return this._customerRepo; } } public ISalesRepository SalesRepo { get { if (this._salesRepo == null) { this._salesRepo = new SalesRepository(this._uow); } return this._salesRepo; } } public bool Validate(Sales sales) { //this is where validation performed return true; } }
控制器:
public SalesController : Controller { private UnitOfWork _uow = new UnitOfWork(); private SalesBusinessLogic _bl = new SalesBusinessLogic(this._uow); public ActionResult Index() { var sales = _bl.SalesRepo.Find(1); sales.CustomerID = 1; if _bl.Validate(sales) { _bl.SalesRepo.Update(sales); _uow.Save(); } return View(sales); } }
这里UnitOfWork仅作为dbcontext的提供者,它将被业务逻辑和存储库使用.
存储库将在BusinessLogic类中.
服务器端验证将由BusinessLogic处理,客户端验证将由Web Layer中的viewmodel处理.
我唯一关心的是UnitofWork中的dbcontext是公共可访问的.
我在正确的方向吗?
解决方法
What if it takes hours from data retrieval until the client click save button. From what i know,we have to keep context as short as possible.
这不是问题 – 控制器是按请求实例化的.用户查看页面时不会保留.听起来你误解了控制器实例化的时间.当您在控制器的构造函数中实例化UnitOfWork时,流程如下所示:
>用户发出POST请求(单击“保存”).
>请求到达服务器并实例化控制器(从而实例化工作单元).
>调用操作方法.
>工作单位处理完毕.
Where should i put business logic? Do i put it in repository? So i would call UoW.departmentRepository.Validate(department) before save. But then,what if i need to validate entity which relate to other entity. Do i call UoW.departmentRepository.Validate(course,department)?
通常,您的业务逻辑将被抽象为位于Web应用程序和存储库之间的单独层.向您展示直接注入控制器的存储库的教程假设您具有“瘦”业务逻辑.
但是,验证肯定不是存储库的工作.您应该为每个视图创建一个单独的视图模型,并验证控制器中的视图模型.存储库应该仅用于CRUD操作.