c# – 将代码移动到服务层的最佳实践
我问过一个关于在我的控制器中将ViewModel映射到Entity Framework模型的最佳实践的问题,并且建议我的代码是正确的(使用LINQ投影),尽管可以另外使用AutoMapper.
现在我觉得我需要/想要将Controller方法中发生的大部分内容移动到新的Service层,这样我就可以在需要时在此层添加业务逻辑,然后在我的控制器中进行方法调用.但我不确定该怎么做.我的ViewModel当然都会保留在Web项目中,那么我的服务层中的方法应该是什么样子以及我在哪里/如何映射ViewModel? 以下是当前GET和POST控制器方法的示例: public ActionResult Laboratories() { var context = new PASSEntities(); var model = (from a in context.Laboratories select new LaboratoryViewModel() { ID = a.ID,Description = a.Description,LabAdmins = (from b in context.Users_Roles join c in context.Users on b.User_ID equals c.ID where b.Laboratory_ID == a.ID select new LabAdminViewModel() { ID = b.ID,User_ID = b.User_ID,Role_ID = b.Role_ID,Laboratory_ID = b.Laboratory_ID,BNL_ID = c.BNL_ID,First_Name = c.Pool.First_Name,Last_Name = c.Pool.Last_Name,Account = c.Account }) }); return View(model); } [HttpPost] public ActionResult AddLaboratory(LaboratoryViewModel model) { try { using (PASSEntities context = new PASSEntities()) { var laboratory = new Laboratory() { ID = model.ID,Description = model.Description }; context.Laboratories.Add(laboratory); context.SaveChanges(); } return RedirectToAction("Laboratories"); } catch { return View(); } } 解决方法
您的服务层应该返回您的域模型.控制器负责将它们映射到视图模型并将其返回到视图.一个小例子:
public ActionResult Laboratories() { // Get the laboratories domain models from the service layer. var laboratories = _laboratoryService.GetLaboratories(); // Map the domain models to view models using AutoMapper. var laboratoriesModel = Mapper.Map<List<LaboratoryViewModel>>(laboratories); // Return view model to the view. return View(laboratoriesModel); } 使用此方法,您需要一个核心/域层,您的域实体可以在其中存在.服务层包含业务逻辑并与域模型交互(例如通过存储库)并将实体化对象返回给控制器.正如您所建议的那样,您的视图模型应该确实位于网站项目中. 另请查看this question,其中我提供了类似解决方案的示例. 更新 服务层中的GetLaborarties方法返回(模型)域模型的集合: public List<Laboratory> GetLaboratories() { return _db.Laboratories.ToList(); } 现在,在控制器中调用此方法并将其映射到视图模型.您可以使用Linq Select方法执行此操作: public ActionResult Laboratories() { // Get the laboratories domain models from the service layer. var laboratories = _laboratoryService.GetLaboratories(); var laboratoriesModel = laboratories.Select(new LaboratoryViewModel { // Map here.. }).ToList(); return View(laboratoriesModel); } 或者如上所述使用AutoMapper. 更新2 具有相关对象的导航属性的简单示例: 假设我们有这个域模型: public class Category { public string Name { get; set; } public string UrlName { get; set; } // Other properties.. public virtual ICollection<Product> Products { get; set; } } 我们可以在服务层创建一个方法: public CategoryService : ICategoryService { public Category GetByName(string name) { return _categoryRepository.Table .Include(c => c.Products) // Include related products .FirstOrDefault(c => c.UrlName = name); } } 我配置了实体框架,类别包含零个或多个产品.使用Include方法,我要求Entity Framework在sql查询中包含相关产品.现在产品将包含该类别的所有相关产品. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |