Asp.net mvc 多层解决方案-类型“Customer”在未引用的程序集中定义
我的解决方案有以下布局 数据层 实体层POCO创建代码优先数据库 服务层Web API 用于表示的Web层MVC层 我在WebAPI层中创建了模拟实体层中实体的模型,以便更容易地引用属性。我有叫模特的。我想让API层做数据工作,以防我以后想升级Web层或转到另一个方向。我使用了VS2019控制器创建工具,并引用了我的服务层模型作为数据层的模型和数据上下文。我得到以下错误:Asp.net mvc 多层解决方案-类型“Customer”在未引用的程序集中定义,asp.net-mvc,visual-studio,entity-framework,asp.net-web-api,Asp.net Mvc,Visual Studio,Entity Framework,Asp.net Web Api,我的解决方案有以下布局 数据层 实体层POCO创建代码优先数据库 服务层Web API 用于表示的Web层MVC层 我在WebAPI层中创建了模拟实体层中实体的模型,以便更容易地引用属性。我有叫模特的。我想让API层做数据工作,以防我以后想升级Web层或转到另一个方向。我使用了VS2019控制器创建工具,并引用了我的服务层模型作为数据层的模型和数据上下文。我得到以下错误: "Error CS0012 The type 'Customer' is defined in an assembly
"Error CS0012 The type 'Customer' is defined in an assembly that is not referenced. You must add a reference to assembly 'XX.Entities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.XX.Services"
我可以理解为什么我会这样,服务层中的模型虽然匹配属性,但与名称空间不匹配。如果不使用AutoMapper之类的工具,如何引用数据层?似乎我遗漏了一些明显的东西,但可能没有。如果您的服务层将包含您的逻辑并与您的实体进行交互,而您的MVC控制器基本上是贫血的,通过服务,听起来您希望您的服务返回模型DTO或ViewModels,它们将从实体返回的数据解耦 要做到这一点,服务将需要引用您的实体,因为这就是您的数据层。理想情况下,数据层应该返回IQueryable,而不是IEnumerable或TEntity,这样服务就可以优化查询以提高效率,而不必返回超出其需要的数据,或者在数据层中增加大量复杂性或大量类似的单用途方法 我不确定您对Automapper的厌恶是什么,但它非常适合处理实体和ViewModel之间的数据转换和复制。您当然可以不用Automapper使用Linq的Select方法来完成它 例如,要从服务中获取OrderModels列表,请执行以下操作:
public IEnumerable<OrderModel> GetOrdersForCustomer(int customerId, int pageNumber, int pageSize)
{
var orders = OrderRepository.GetByCustomerId(customerId)
.OrderByDescending(x => x.CreatedAt)
.Select(x => new OrderModel
{
OrderId = x.OrderId,
OrderNumber = x.OrderNumber,
CreatedAt = x.CreatedAt,
// ... et al,
OrderItems = x.OrderItems.Select( oi => new OrderItemModel
{
OrderItemId = oi.OrderItemId,
ProductId = oi.Product.ProductId,
ProductName = oi.Product.Name,
Quantity = oi.Quantity,
UnitPrice = oi.Product.Price,
// ...
}).ToList()
}).Skip(pageNumber*pageSize)
.Take(pageSize)
.ToList();
return orders;
}
更新:
var existingOrder = _context.Orders.Single(x => x.OrderId = orderViewModel.OrderId);
_mapper.Map(orderViewModel, existingOrder);
_context.SaveChanges();
。。。对于单个实体,你已经完成了很多。可能需要做更多的工作来更新订单中的相关实体。感谢您的解释,这正是我想要的。我并不完全反对使用AutoMapper,根据您的解释,我可能会。我在想,也许我把一切都复杂化了,不需要AutoMapper。我真的很喜欢几乎完全脱离我的服务层的想法,这样我就可以管理它,而我的开发人员(我是领导者)可以在新的数据功能可用时更新UI。
var newOrder = _mapper.Map<Order>(orderViewModel);
_context.Orders.Add(newOrder);
_context.SaveChanges();
var existingOrder = _context.Orders.Single(x => x.OrderId = orderViewModel.OrderId);
_mapper.Map(orderViewModel, existingOrder);
_context.SaveChanges();