C# 从服务层返回包含多个实体的DTO对象

C# 从服务层返回包含多个实体的DTO对象,c#,asp.net-mvc-5,automapper,repository-pattern,C#,Asp.net Mvc 5,Automapper,Repository Pattern,我正在使用存储库模式开发一个.net多层应用程序。实现存储库模式的数据访问层具有将数据返回到服务层的方法,而服务层又将数据返回到web api层。目前,我已经编写了返回客户信息或订单信息的方法。我还需要编写返回CustomerOrder信息的方法。我认为最好的地方是在服务层编写,但不确定如何进行。我在服务层中创建了一个DTO对象,其中包含Customer和Order类的字段。服务层是编写此逻辑的最佳位置。我想我必须在服务层中填充Dto对象,并将该对象返回到表示层。谁能给我指一下路吗 实体层 p

我正在使用存储库模式开发一个.net多层应用程序。实现存储库模式的数据访问层具有将数据返回到服务层的方法,而服务层又将数据返回到web api层。目前,我已经编写了返回客户信息或订单信息的方法。我还需要编写返回CustomerOrder信息的方法。我认为最好的地方是在服务层编写,但不确定如何进行。我在服务层中创建了一个DTO对象,其中包含Customer和Order类的字段。服务层是编写此逻辑的最佳位置。我想我必须在服务层中填充Dto对象,并将该对象返回到表示层。谁能给我指一下路吗

实体层

 public class Customers
    {


        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public Gender Gender { get; set; }
        public string Email { get; set; }

        public Address Address { get; set; }

        public int AddressId { get; set; }


        public ICollection<Orders> Orders { get; set; }

    }
    public class Orders
    {
        public int Id { get; set; }

        public DateTime? OrderDate { get; set; }
        public int? OrderNumber { get; set; }

        public Customers Customers { get; set; }

        public int CustomerId { get; set; }

        public ICollection<ProductOrder> ProductOrders { get; set; }
    }

   public class Address
    {
        public int Id { get; set; }

        public string Address1 { get; set; }

        public string Address2 { get; set; }

        public string City { get; set; }

        public State State { get; set; }

        public int StateId { get; set; }


        public ICollection<Customers> Customers { get; set; }


        public string ZipCode { get; set; }
    }
 public class CustomerRepository : RepositoryBase<Customers>, ICustomerRepository
    {
        public CustomerRepository(IDbFactory dbFactory)
            : base(dbFactory) { }



        public IEnumerable<Customers> GetAllCustomers()
        {
            return (from customer in this.DbContext.Customers
                    select customer).ToList();
        }

    }

    public interface ICustomerRepository : IRepository<Customers>
    {
        IEnumerable<Customers> GetAllCustomers();

    }


 public class OrderRepository : RepositoryBase<Orders>, IOrderRepository
    {
        public OrderRepository(IDbFactory dbFactory)
            : base(dbFactory) {}

        public IEnumerable<Orders> GetAllOrders()
        {
            return (from order in this.DbContext.Orders
                    select order).ToList();
        }

    }

    public interface IOrderRepository : IRepository<Orders>
    {
        IEnumerable<Orders> GetAllOrders();
    }
    public interface ICustomerService
        {
            IEnumerable<Customers> GetCustomers();
        }

        public class CustomerService : ICustomerService
        {
            private readonly ICustomerRepository _customerRepository;
            private readonly IUnitOfWork _unitOfWork;

            public CustomerService(ICustomerRepository customerRepository, IUnitOfWork unitOfWork)
            {
                this._customerRepository = customerRepository;
                this._unitOfWork = unitOfWork;
            }


            public IEnumerable<Customers> GetCustomers()
            {
                return _customerRepository.GetAll();
            }




 public interface IOrderService
        {
            IEnumerable<Orders> GetOrders();

        }

        public class OrderService : IOrderService
        {
            private readonly IOrderRepository _orderRepository;
            private readonly IUnitOfWork _unitOfWork;

            public OrderService(IOrderRepository orderRepository, IUnitOfWork unitOfWork)
            {
                this._orderRepository = orderRepository;
                this._unitOfWork = unitOfWork;
            }
           }

            public IEnumerable<Orders> GetOrders()
            {
                return _orderRepository.GetAll();
            }
           }
  public class CustomerDto
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Gender { get; set; }
        public string Email { get; set; }

    }



public class OrderDto
{
    public int Id { get; set; }
    public DateTime? OrderDate { get; set; }
    public int? OrderNumber { get; set; }
}
public class CustomerOrderDto
{
    public CustomerDto Customer { get; set; }
    public OrderDto Order { get; set; }

}
public class DomainToDtoMapping : Profile
{
    public override string ProfileName
    {
        get { return "DomainToDtoMapping"; }
    }

    [Obsolete]
    protected override void Configure()
    {
        CreateMap<Customers, CustomerDto>();
        CreateMap<Address, AddressDto>();
        CreateMap<Orders, OrderDto>();
        CreateMap<OrdersDetails, OrderDetailsDto>();
        CreateMap<State, StateDto>();


        CreateMap<CustomerDto, CustomerOrderDto>();
        CreateMap<AddressDto, CustomerOrderDto>();
        CreateMap<OrderDto, CustomerOrderDto>();
        CreateMap<OrderDetailsDto, CustomerOrderDto>();
        CreateMap<State, CustomerOrderDto>();

    }
}
服务层中的映射(域对象到Dto)

 public class Customers
    {


        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public Gender Gender { get; set; }
        public string Email { get; set; }

        public Address Address { get; set; }

        public int AddressId { get; set; }


        public ICollection<Orders> Orders { get; set; }

    }
    public class Orders
    {
        public int Id { get; set; }

        public DateTime? OrderDate { get; set; }
        public int? OrderNumber { get; set; }

        public Customers Customers { get; set; }

        public int CustomerId { get; set; }

        public ICollection<ProductOrder> ProductOrders { get; set; }
    }

   public class Address
    {
        public int Id { get; set; }

        public string Address1 { get; set; }

        public string Address2 { get; set; }

        public string City { get; set; }

        public State State { get; set; }

        public int StateId { get; set; }


        public ICollection<Customers> Customers { get; set; }


        public string ZipCode { get; set; }
    }
 public class CustomerRepository : RepositoryBase<Customers>, ICustomerRepository
    {
        public CustomerRepository(IDbFactory dbFactory)
            : base(dbFactory) { }



        public IEnumerable<Customers> GetAllCustomers()
        {
            return (from customer in this.DbContext.Customers
                    select customer).ToList();
        }

    }

    public interface ICustomerRepository : IRepository<Customers>
    {
        IEnumerable<Customers> GetAllCustomers();

    }


 public class OrderRepository : RepositoryBase<Orders>, IOrderRepository
    {
        public OrderRepository(IDbFactory dbFactory)
            : base(dbFactory) {}

        public IEnumerable<Orders> GetAllOrders()
        {
            return (from order in this.DbContext.Orders
                    select order).ToList();
        }

    }

    public interface IOrderRepository : IRepository<Orders>
    {
        IEnumerable<Orders> GetAllOrders();
    }
    public interface ICustomerService
        {
            IEnumerable<Customers> GetCustomers();
        }

        public class CustomerService : ICustomerService
        {
            private readonly ICustomerRepository _customerRepository;
            private readonly IUnitOfWork _unitOfWork;

            public CustomerService(ICustomerRepository customerRepository, IUnitOfWork unitOfWork)
            {
                this._customerRepository = customerRepository;
                this._unitOfWork = unitOfWork;
            }


            public IEnumerable<Customers> GetCustomers()
            {
                return _customerRepository.GetAll();
            }




 public interface IOrderService
        {
            IEnumerable<Orders> GetOrders();

        }

        public class OrderService : IOrderService
        {
            private readonly IOrderRepository _orderRepository;
            private readonly IUnitOfWork _unitOfWork;

            public OrderService(IOrderRepository orderRepository, IUnitOfWork unitOfWork)
            {
                this._orderRepository = orderRepository;
                this._unitOfWork = unitOfWork;
            }
           }

            public IEnumerable<Orders> GetOrders()
            {
                return _orderRepository.GetAll();
            }
           }
  public class CustomerDto
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Gender { get; set; }
        public string Email { get; set; }

    }



public class OrderDto
{
    public int Id { get; set; }
    public DateTime? OrderDate { get; set; }
    public int? OrderNumber { get; set; }
}
public class CustomerOrderDto
{
    public CustomerDto Customer { get; set; }
    public OrderDto Order { get; set; }

}
public class DomainToDtoMapping : Profile
{
    public override string ProfileName
    {
        get { return "DomainToDtoMapping"; }
    }

    [Obsolete]
    protected override void Configure()
    {
        CreateMap<Customers, CustomerDto>();
        CreateMap<Address, AddressDto>();
        CreateMap<Orders, OrderDto>();
        CreateMap<OrdersDetails, OrderDetailsDto>();
        CreateMap<State, StateDto>();


        CreateMap<CustomerDto, CustomerOrderDto>();
        CreateMap<AddressDto, CustomerOrderDto>();
        CreateMap<OrderDto, CustomerOrderDto>();
        CreateMap<OrderDetailsDto, CustomerOrderDto>();
        CreateMap<State, CustomerOrderDto>();

    }
}
公共类域映射:配置文件
{
公共重写字符串配置文件名
{
获取{返回“域映射”;}
}
[过时]
受保护的覆盖无效配置()
{
CreateMap();
CreateMap();
CreateMap();
CreateMap();
CreateMap();
CreateMap();
CreateMap();
CreateMap();
CreateMap();
CreateMap();
}
}
试试这个:

public interface IOrderService
    {
        IEnumerable<CustomerOrderDto> GetOrders();
    }

 public IEnumerable<CustomerOrderDto> GetOrders()
    {
        List<CustomerOrderDto> customerOrderList = new List<CustomerOrderDto>();

        foreach (var item in customerOrderList)
        {
            CustomerOrderDto customerOrder = new CustomerOrderDto();
            //fields mapping

            customerOrderList.Add(customerOrder);
        }


        return customerOrderList;
    }
公共接口服务
{
IEnumerable GetOrders();
}
公共IEnumerable GetOrders()
{
List customerOrderList=新列表();
foreach(customerOrderList中的var项)
{
CustomerOrderTo customerOrder=新CustomerOrderTo();
//字段映射
customerOrderList.Add(customerOrder);
}
返回customerOrderList;
}

最好的映射方法是linq或this。你不应该使用Automapper,因为它太慢了。

你考虑过实现吗

您的
customerOrderTo
将包含
customerTo
OrderDto
类。像这样:

public class CustomerOrderDto
{
    public CustomerDto Customer {get; set;}
    public OrderDto Order {get; set;}
}
实施此模式将带来以下好处:

  • 将来对
    客户订单收件人
    订单收件人
    的任何更改都将自动成为
    客户订单收件人
    的一部分
  • 用于将数据映射到
    dto
    类的代码可用于映射单个
    dto
    实体以及“CustomerOrderTo”
  • 将实体类映射到DTO类的代码应该在服务层中

    将客户实体映射到CustomerTo实体:

        internal static CustomerDto Map(Customer entity)
        {
            if (entity == null) throw new ArgumentNullException("entity");
    
            CustomerDto dto = new CustomerDto();
            try
            {
                dto.Id = entity.Id;
                dto.FirstName = entity.FirstName;
                dto.LastName = entity.LastName;
                dto.Gender = entity.Gender;
                dto.Email = entity.Email;
            }
            catch (Exception e)
            {
                string errMsg = String.Format("Map(entity). Error mapping a Customer entity to DTO. Id: {0}.", entity.Id);
                //LOG ERROR
            }
    
            return dto;
        }
    

    您是否已完成用于检索复合CustomerOrder实体的存储库层?我看到你有完整的
    GetAllCustomers()
    GetAllOrders()

    存储库代码,我将如何将客户、订单、地址实体映射到CustomerOrderd,在这里为每个实体创建dto并进行映射。我已经更新了帖子,展示了AutoMapper的使用。如果AutoMapper速度慢,它有什么好处。我看到很多人推荐AutoMapper。我不使用AutoMapper进行映射过程。性能最好的使用linq,但如果您想使用AutoMapper。对于每个实体类,请在基类中创建。请参阅:Shai Cohen答案。我可能在这里遗漏了一些内容,但看起来您正在迭代刚刚实例化的
    customerOrderList
    。您不应该在
    DataReader
    或类似的东西上迭代吗?理想情况下,您的服务层将只返回DTO,您将使用(比如)Automapper将数据库实体映射到DTO。现在,您可以独立于数据库层开发服务接口,并可以将数据库实体组合到DTO中,以从服务层返回。除了复杂性之外,问题是,增加一个存储层会带来什么好处…伙计,您真的需要MediatR。所有这些图层对象对您没有任何好处。折叠那些层!你还在研究这个问题的解决方案吗?你是说使用复合模式,我可以简单地在服务类中创建一个方法,该方法将返回此CustomerOrderTo,并且自动映射器将处理映射显示。在将此DTO发送到演示层之前,我将以与今天填充
    CustomerTo
    OrderDto
    实体相同的方式填充此DTO。您只需将每个类发送到其相关的映射函数。我可能遗漏了一些东西,但我没有看到您问题中的两种映射方法。如果您可以添加这些(或者向我指出,如果它们已经存在的话),我将能够更具体地回答您的问题。我所做的唯一映射是域到dto的映射,如我上面的帖子所示。根据您的建议,我创建了单个dto和复合dto。下一步我需要做什么。你能给我举个例子说明如何填充CustomerOrderTo对象吗?我很乐意。您能为
    CustomerDto
    OrderDto
    实体提供映射功能吗?