private void MapperConfigure(MapperInstance cfd)
        {
            cfd.AddMap<Person, PersonInfoDto>(src =>
            {
                PersonInfoDto dst = new PersonInfoDto();
                dst.InjectFrom(src);
                dst.EmployeeBrithDate = src.Employee?.BirthDate;

                return dst;
            });

            cfd.AddMap<EmailAddress, EmailDto>(src =>
            {
                EmailDto dst = new EmailDto();
                dst.InjectFrom(src);
                dst.EmailAddress = src.EmailAddress1;

                return dst;
            });

            cfd.AddMap<ShipMethod, ShipMethodDto>(src =>
            {
                ShipMethodDto dst = new ShipMethodDto();
                dst.InjectFrom(src);
                return dst;
            });

            cfd.AddMap<ProductListPriceHistory, ProductListPriceHistoryDto>(src =>
            {
                ProductListPriceHistoryDto dst = new ProductListPriceHistoryDto();
                dst.InjectFrom(src);
                return dst;
            });

            cfd.AddMap<Product, ProductDto>(src =>
            {
                ProductDto dst = new ProductDto();
                dst.InjectFrom(src);
                dst.ProductListPriceHistories = new List<ProductListPriceHistoryDto>();
                foreach (ProductListPriceHistory item in src.ProductListPriceHistories)
                {
                    ProductListPriceHistoryDto itemDto = new ProductListPriceHistoryDto();
                    itemDto.InjectFrom(item);

                    dst.ProductListPriceHistories.Add(itemDto);
                }

                return dst;
            });

            cfd.AddMap<ProductModel, ProductModelDto>(src =>
            {
                ProductModelDto dst = new ProductModelDto();
                dst.InjectFrom(src);
                return dst;
            });

            cfd.AddMap<Product, Product2Dto>(src =>
            {
                Product2Dto dst = new Product2Dto();
                dst.InjectFrom(src);
                dst.ProductModel = new ProductModelDto();
                dst.ProductModel.InjectFrom(src.ProductModel);
                dst.ProductModelID = src.ProductModel?.ProductModelID;

                return dst;
            });
        }
        public ProductDto GetProduct(int id)
        {
            Product product = this.dbContext.Products.Find(id);
            if (product == null)
            {
                throw new ArgumentException("id");
            }

            ProductDto productDto = new ProductDto();
            productDto.ProductID = product.ProductID;
            productDto.Name = product.Name;
            productDto.ProductNumber = product.ProductNumber;
            productDto.MakeFlag = product.MakeFlag;
            productDto.FinishedGoodsFlag = product.FinishedGoodsFlag;
            productDto.Color = product.Color;
            productDto.SafetyStockLevel = product.SafetyStockLevel;
            productDto.ReorderPoint = product.ReorderPoint;
            productDto.StandardCost = product.StandardCost;
            productDto.ListPrice = product.ListPrice;
            productDto.Size = product.Size;
            productDto.SizeUnitMeasureCode = product.SizeUnitMeasureCode;
            productDto.WeightUnitMeasureCode = product.WeightUnitMeasureCode;
            productDto.Weight = product.Weight;
            productDto.DaysToManufacture = product.DaysToManufacture;
            productDto.ProductLine = product.ProductLine;
            productDto.Class = product.Class;
            productDto.Style = product.Style;
            productDto.ProductSubcategoryID = product.ProductSubcategoryID;
            productDto.ProductModelID = product.ProductModelID;
            productDto.SellStartDate = product.SellStartDate;
            productDto.SellEndDate = product.SellEndDate;
            productDto.DiscontinuedDate = product.DiscontinuedDate;
            productDto.rowguid = product.rowguid;
            productDto.ModifiedDate = product.ModifiedDate;

            productDto.ProductListPriceHistories = new List<ProductListPriceHistoryDto>();
            foreach (ProductListPriceHistory productListPriceHistory in product.ProductListPriceHistories)
            {
                ProductListPriceHistoryDto productListPriceHistoryDto = new ProductListPriceHistoryDto();
                productListPriceHistoryDto.EndDate = productListPriceHistory.EndDate;
                productListPriceHistoryDto.ListPrice = productListPriceHistory.ListPrice;
                productListPriceHistoryDto.ModifiedDate = productListPriceHistory.ModifiedDate;
                productListPriceHistoryDto.ProductID = productListPriceHistory.ProductID;
                productListPriceHistoryDto.StartDate = productListPriceHistory.StartDate;

                productDto.ProductListPriceHistories.Add(productListPriceHistoryDto);
            }


            return productDto;
        }
        public ProductDto GetProduct(int id)
        {

            string sql = @"SELECT
       [p].[ProductID]
      ,[p].[Name]
      ,[p].[ProductNumber]
      ,[p].[MakeFlag]
      ,[p].[FinishedGoodsFlag]
      ,[p].[Color]
      ,[p].[SafetyStockLevel]
      ,[p].[ReorderPoint]
      ,[p].[StandardCost]
      ,[p].[ListPrice]
      ,[p].[Size]
      ,[p].[SizeUnitMeasureCode]
      ,[p].[WeightUnitMeasureCode]
      ,[p].[Weight]
      ,[p].[DaysToManufacture]
      ,[p].[ProductLine]
      ,[p].[Class]
      ,[p].[Style]
      ,[p].[ProductSubcategoryID]
      ,[p].[ProductModelID]
      ,[p].[SellStartDate]
      ,[p].[SellEndDate]
      ,[p].[DiscontinuedDate]
      ,[p].[rowguid]
      ,[p].[ModifiedDate]
      ,[Plph].[EndDate]
      ,[Plph].[ListPrice]
      ,[Plph].[ModifiedDate]
      ,[Plph].[ProductID]
      ,[Plph].[StartDate]
  FROM [AdventureWorks2014].[Production].[Product] [p]
  LEFT JOIN [AdventureWorks2014].[Production].[ProductListPriceHistory] [Plph]
  ON [p].[ProductID] = [Plph].[ProductID]
  WHERE [p].[ProductID] = @Id;";

            using (SqlConnection connection = new SqlConnection(this.connectionString))
            {
                SqlCommand cmd = connection.CreateCommand();
                cmd.CommandText = sql;
                cmd.CommandType = System.Data.CommandType.Text;

                cmd.Parameters.AddWithValue("@Id", id);

                bool isFirst = true;
                ProductDto productDto = new ProductDto();
                productDto.ProductListPriceHistories = new List<ProductListPriceHistoryDto>();

                if (connection.State != System.Data.ConnectionState.Open)
                {
                    connection.Open();
                }

                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        if (isFirst)
                        {
                            productDto.ProductID = (int)reader["ProductID"];
                            productDto.Name = this.MapToString(reader, "Name");
                            productDto.ProductNumber = this.MapToString(reader, "ProductNumber");
                            productDto.MakeFlag = (bool)reader["MakeFlag"];
                            productDto.FinishedGoodsFlag = (bool)reader["FinishedGoodsFlag"];
                            productDto.Color = this.MapToString(reader, "Color");
                            productDto.SafetyStockLevel = (short)reader["SafetyStockLevel"];
                            productDto.ReorderPoint = (short)reader["ReorderPoint"];
                            productDto.StandardCost = (decimal)reader["StandardCost"];
                            productDto.ListPrice = (decimal)reader["ListPrice"];
                            productDto.Size = this.MapToString(reader, "Size");
                            productDto.SizeUnitMeasureCode = this.MapToString(reader, "SizeUnitMeasureCode");
                            productDto.WeightUnitMeasureCode = this.MapToString(reader, "WeightUnitMeasureCode");
                            productDto.Weight = this.MapToDecimal(reader, "Weight");
                            productDto.DaysToManufacture = (int)reader["DaysToManufacture"];
                            productDto.ProductLine = this.MapToString(reader, "ProductLine");
                            productDto.Class = this.MapToString(reader, "Class");
                            productDto.Style = this.MapToString(reader, "Style");
                            productDto.ProductSubcategoryID = this.MapToInt(reader, "ProductSubcategoryID");
                            productDto.ProductModelID = this.MapToInt(reader, "ProductModelID");
                            productDto.SellStartDate = (DateTime)reader["SellStartDate"];
                            productDto.SellEndDate = this.MapToDateTime(reader, "SellEndDate");
                            productDto.DiscontinuedDate = this.MapToDateTime(reader, "DiscontinuedDate");
                            productDto.rowguid = (Guid)reader["rowguid"];
                            productDto.ModifiedDate = (DateTime)reader["ModifiedDate"];

                            isFirst = false;
                        }

                        DateTime? stratDate = this.MapToDateTime(reader, "StartDate");
                        if (stratDate.HasValue)
                        {
                            ProductListPriceHistoryDto productListPriceHistoryDto = new ProductListPriceHistoryDto();
                            productListPriceHistoryDto.StartDate = stratDate.Value;
                            productListPriceHistoryDto.EndDate = this.MapToDateTime(reader, "EndDate");
                            productListPriceHistoryDto.ListPrice = (decimal)reader["ListPrice"];
                            productListPriceHistoryDto.ModifiedDate = (DateTime)reader["ModifiedDate"];
                            productListPriceHistoryDto.ProductID = (int)reader["ProductID"];

                            productDto.ProductListPriceHistories.Add(productListPriceHistoryDto);
                        }
                    }
                }

                if (isFirst)
                {
                    throw new ArgumentException("id");
                }

                return productDto;
            }
        }