加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 将代码移动到服务层的最佳实践

发布时间:2020-12-16 01:57:50 所属栏目:百科 来源:网络整理
导读:我问过一个关于在我的控制器中将ViewModel映射到Entity Framework模型的最佳实践的问题,并且建议我的代码是正确的(使用LINQ投影),尽管可以另外使用AutoMapper. 现在我觉得我需要/想要将Controller方法中发生的大部分内容移动到新的Service层,这样我就可以在
我问过一个关于在我的控制器中将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查询中包含相关产品.现在产品将包含该类别的所有相关产品.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读