MVC Mapping层访问服务层

时间:2015-09-05 14:51:33

标签: c# asp.net-mvc entity-framework

我设计了我的应用程序(带有EF6的ASP.NET MVC),因此有一个Mapping层负责来回实现从Entities到ViewModels的映射。它由控制器使用,因此基本上通常的Edit操作看起来像

var entity = DataService.Get(viewModel.Id);
entity = Mapper.MapToEntity(viewModel, entity);
DataService.Update(entity);

基础MapToEntity实现使用AutoMapper来映射对象的基本属性。

Update()在EF6中实现为一个函数,它将实体标记为已修改并调用底层上下文SaveChanges()。

但是,对于更复杂的映射,例如具有相关实体的实体,例如一个Order,Mapper类执行更多操作。例如,使用ViewModel相关对象数据更新相关实体对象(OrderDetails),将父Id(OrderId)分配给新子对象,最后解决有问题的问题:删除子对象。

现在,我的专业Mappers引用了相关实体的Service Object,它有一个MarkEntityToDelete函数,只是在底层DbSet中标记要删除的实体。

foreach (var orderDetail in viewModel.OrderDetails.Where(d => d.Id != 0 || d.Delete == false))
{
    var orderDetailToUpdate = orderDetail.Id == 0 ? new OrderDetail() : _orderDataService.GetOrderDetail(orderDetail.Id);

    if (orderDetail.Delete)
    {
        _orderDataService.MarkLineaAsDeleted(orderDetailToUpdate);
    }
    else
    {
        Mapper.Map(orderDetail, orderDetailToUpdate);

        if (orderDetail.Id != 0) continue;

        orderDetailToUpdate.MantenimientoId = order.Id;
        order.OrderDetails.Add(orderDetailToUpdate);
    }
}

这是一个依赖,只是因为实现使用EF6并且事务边界在Service内部,所以Mapper不能直接删除该对象,只需将其标记为删除。

虽然这种解决方案在实践中运作良好,但我并不是特别喜欢它。我不认为Mapper对象应该以这种方式依赖于Service对象,只是为了标记要删除的子对象。 我尝试使用以下代码:

entity.EntregasCuenta.Remove(entity.EntregasCuenta.Single(e => e.Id == entregaCuenta.Id));

但它会产生外键检查错误,这是预期的,因为我不会删除相关实体但是关系。

所以我的问题是,映射器应该如何处理这种情况?从ViewModel到实体的映射应该由Mapping层完成,但是更新相关实体应该由Service完成。最后,Controller的责任应该只是按顺序调用这三个操作,即检索实体(服务),将viewmodel数据映射到实体(映射层),更新更改(服务)。

我错过了什么吗?

0 个答案:

没有答案