Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 多层解决方案-类型“Customer”在未引用的程序集中定义_Asp.net Mvc_Visual Studio_Entity Framework_Asp.net Web Api - Fatal编程技术网

Asp.net mvc 多层解决方案-类型“Customer”在未引用的程序集中定义

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

我的解决方案有以下布局

数据层 实体层POCO创建代码优先数据库 服务层Web API 用于表示的Web层MVC层 我在WebAPI层中创建了模拟实体层中实体的模型,以便更容易地引用属性。我有叫模特的。我想让API层做数据工作,以防我以后想升级Web层或转到另一个方向。我使用了VS2019控制器创建工具,并引用了我的服务层模型作为数据层的模型和数据上下文。我得到以下错误:

"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();