//public IActionResult Index()
        public IActionResult Index(int?categoryId)
        {
            //var productsFilter = new ProductsReportFilterModel();
            var productsFilter = new ProductsReportFilterModel()
            {
                CategoryId = categoryId
            };

            var page = new PageModel()
            {
                RecordsPerPageCount = AppSettings.RecordsPerPageCount
            };
            var result = _productService.GetProductsReport(productsFilter, page);

            if (result.Status == ResultStatus.Exception)
            {
                throw new Exception(result.Message);
            }
            var productsReport = result.Data;

            #region Paging
            double recordsCount        = page.RecordsCount;                                // filtrelenmiş veya filtrelenmemiş toplam kayıt sayısı
            double recordsPerPageCount = page.RecordsPerPageCount;                         // sayfa başına kayıt sayısı
            double totalPageCount      = Math.Ceiling(recordsCount / recordsPerPageCount); // toplam sayfa sayısı
            List <SelectListItem> pageSelectListItems = new List <SelectListItem>();
            if (totalPageCount == 0)
            {
                pageSelectListItems.Add(new SelectListItem()
                {
                    Value = "1",
                    Text  = "1"
                });
            }
            else
            {
                for (int pageNumber = 1; pageNumber <= totalPageCount; pageNumber++)
                {
                    pageSelectListItems.Add(new SelectListItem()
                    {
                        Value = pageNumber.ToString(),
                        Text  = pageNumber.ToString()
                    });
                }
            }
            #endregion

            var viewModel = new ProductsReportAjaxIndexViewModel()
            {
                ProductsReport = productsReport,
                ProductsFilter = productsFilter,
                Pages          = new SelectList(pageSelectListItems, "Value", "Text"),

                // Categories artık view component üzerinden kullanıldığı için tekrar doldurmaya gerek yok
                //Categories = new SelectList(_categoryService.Query().ToList(), "Id", "Name")
            };

            return(View(viewModel));
        }
        //[Obsolete("Bu methodun daha yeni bir versiyonu bulunmaktadır.")]
        // obsolete: kullanıldığı yerde kullanıldığı yapının daha yeni bir versiyonu olduğunu ve bu yeni versiyonun kullanılmasının gerektiğini belirtir.
        public Result <List <ProductsReportModel> > GetProductsReport(ProductsReportFilterModel filter, PageModel page = null, OrderModel order = null)
        {
            try
            {
                #region Query
                var productQuery  = _productRepository.EntityQuery();
                var categoryQuery = _categoryRepository.EntityQuery();

                //var query = from p in productQuery
                //            join c in categoryQuery
                //                on p.CategoryId equals c.Id
                //            orderby c.Name, p.Name // *1
                //            select new ProductsReportModel()
                //            {
                //                CategoryDescription = c.Description,
                //                CategoryName = c.Name,
                //                ExpirationDateText = p.ExpirationDate.HasValue
                //                    ? p.ExpirationDate.Value.ToString("MM/dd/yyyy", new CultureInfo("en"))
                //                    : "",
                //                ProductDescription = p.Description,
                //                ProductName = p.Name,
                //                StockAmount = p.StockAmount,
                //                //UnitPriceText = p.UnitPrice.ToString("C2", new CultureInfo("en")), // *2
                //                UnitPriceText = "$" + p.UnitPrice.ToString(new CultureInfo("en")), // *2
                //                CategoryId = c.Id
                //            };
                var query = productQuery.Join(categoryQuery,
                                              p => p.CategoryId,
                                              c => c.Id,
                                              (p, c) => new ProductsReportModel()
                {
                    CategoryDescription = c.Description,
                    CategoryName        = c.Name,
                    ExpirationDateText  = p.ExpirationDate.HasValue
                            ? p.ExpirationDate.Value.ToString("MM/dd/yyyy", new CultureInfo("en"))
                            : "",
                    ProductDescription = p.Description,
                    ProductName        = p.Name,
                    StockAmount        = p.StockAmount,
                    //UnitPriceText = p.UnitPrice.ToString("C2", new CultureInfo("en")), // *2
                    UnitPriceText  = "$" + p.UnitPrice.ToString(new CultureInfo("en")),    // *2
                    CategoryId     = c.Id,
                    UnitPrice      = p.UnitPrice,
                    ExpirationDate = p.ExpirationDate
                });
                #endregion

                #region Query First Order
                query = query.OrderBy(q => q.CategoryName).ThenBy(q => q.ProductName); // *1
                #endregion

                // Sıralama
                #region Order
                if (order != null && !string.IsNullOrWhiteSpace(order.Expression))
                {
                    switch (order.Expression)
                    {
                    case "Product Name":
                        query = order.DirectionAscending
                                ? query.OrderBy(q => q.ProductName)
                                : query.OrderByDescending(q => q.ProductName);
                        break;

                    case "Category Name":
                        query = order.DirectionAscending
                                ? query.OrderBy(q => q.CategoryName)
                                : query.OrderByDescending(q => q.CategoryName);
                        break;

                    case "Unit Price":
                        query = order.DirectionAscending
                                ? query.OrderBy(q => q.UnitPrice)
                                : query.OrderByDescending(q => q.UnitPrice);
                        break;

                    case "Stock Amount":
                        query = order.DirectionAscending
                                ? query.OrderBy(q => q.StockAmount)
                                : query.OrderByDescending(q => q.StockAmount);
                        break;

                    default:     // Expiration Date
                        query = order.DirectionAscending
                                ? query.OrderBy(q => q.ExpirationDate)
                                : query.OrderByDescending(q => q.ExpirationDate);
                        break;
                    }
                }
                #endregion

                #region Query Filter
                if (filter.CategoryId.HasValue)
                {
                    query = query.Where(q => q.CategoryId == filter.CategoryId.Value);
                }
                if (!string.IsNullOrWhiteSpace(filter.ProductName))
                {
                    //query = query.Where(q => q.ProductName.Equals(filter.ProductName.Trim(), StringComparison.OrdinalIgnoreCase));
                    //query = query.Where(q => q.ProductName.Contains(filter.ProductName.Trim(), StringComparison.OrdinalIgnoreCase));
                    query = query.Where(q => q.ProductName.ToUpper().Contains(filter.ProductName.ToUpper().Trim()));
                }
                if (!string.IsNullOrWhiteSpace(filter.UnitPriceBeginText))
                {
                    double unitPriceBegin = Convert.ToDouble(filter.UnitPriceBeginText.Replace(",", "."),
                                                             CultureInfo.InvariantCulture);
                    query = query.Where(q => q.UnitPrice >= unitPriceBegin);
                }
                if (!string.IsNullOrWhiteSpace(filter.UnitPriceEndText))
                {
                    double unitPriceEnd = Convert.ToDouble(filter.UnitPriceEndText.Replace(",", "."),
                                                           CultureInfo.InvariantCulture);
                    query = query.Where(q => q.UnitPrice <= unitPriceEnd);
                }
                if (filter.StockAmountBegin != null)
                {
                    query = query.Where(q => q.StockAmount >= filter.StockAmountBegin.Value);
                }
                if (filter.StockAmountEnd != null)
                {
                    query = query.Where(q => q.StockAmount <= filter.StockAmountEnd.Value);
                }
                if (!string.IsNullOrWhiteSpace(filter.ExpirationDateBeginText)) // 05/09/2021
                {
                    //string day, month, year;
                    //day = filter.ExpirationDateBeginText.Split('/')[1];
                    //month = filter.ExpirationDateBeginText.Split('/')[0];
                    //year = filter.ExpirationDateBeginText.Split('/')[2];
                    //DateTime expirationDateBegin = new DateTime(Convert.ToInt32(year), Convert.ToInt32(month), Convert.ToInt32(day));
                    DateTime expirationDateBegin = DateTime.Parse(filter.ExpirationDateBeginText, new CultureInfo("en"));

                    query = query.Where(q => q.ExpirationDate >= expirationDateBegin);
                }
                if (!string.IsNullOrWhiteSpace(filter.ExpirationDateEndText))
                {
                    DateTime expirationDateEnd = DateTime.Parse(filter.ExpirationDateEndText, new CultureInfo("en"));
                    query = query.Where(q => q.ExpirationDate <= expirationDateEnd);
                }
                #endregion

                #region Query Paging
                if (page != null)
                {
                    page.RecordsCount = query.Count();
                    int skip = (page.PageNumber - 1) * page.RecordsPerPageCount;
                    int take = page.RecordsPerPageCount;
                    query = query.Skip(skip).Take(take); // *1 Önce mutlaka herhangi bir özelliğe veya özelliklere göre sıralama yapılmalı!
                }
                #endregion

                return(new SuccessResult <List <ProductsReportModel> >(query.ToList()));
            }
            catch (Exception exc)
            {
                return(new ExceptionResult <List <ProductsReportModel> >(exc));
            }
        }