How to refactor this LINQ query for a reports dashboard in Blazor Server Application?
![](https://techprofile.blob.core.windows.net/images/PjYbsbDfukmsOVQ24l7Rxw.png?8D8DBE)
Cenk
991
Reputation points
I am building a reports dashboard on my Blazor Server Application that displays the count of the last 3 years of "Completed" and "Continues" orders. The business rules are:
- Completed order means OrderDetails CompletionDateTime is not null (Status = Completed).
- There are 4 statuses (Warehouse, Completed, Order Opened, Shipped).
- Statuses other than "Completed" should be counted as "Continues".
I need help refactoring my LINQ query to meet these requirements. The code and relevant classes are given below.
public async Task<ICollection<ReportAnnualDto>> GetAnnuallyOrders()
{
await using var ctx = await _db.CreateDbContextAsync();
var allYears = Enumerable.Range(DateTime.Now.Year - 2, 3); // last 3 years including this year
var allStatuses = new List<string> { "Completed", "Continues" };
var orders = await ctx.Orders.AsNoTracking()
.GroupBy(x => new { Year = x.OrderDateTime.Year, Status = x.Status })
.Select(u => new ReportAnnualDto()
{
Year = u.Key.Year,
Status = u.Key.Status,
Count = u.Count()
})
.ToListAsync();
var result = allYears.SelectMany(year => allStatuses,
(year, status) => new { Year = year, Status = status })
.GroupJoin(
orders,
all => new { all.Year, all.Status },
order => new { order.Year, order.Status },
(all, orderGroup) => orderGroup
.Select(order => new ReportAnnualDto { Year = all.Year, Status = all.Status, Count = order.Count })
.DefaultIfEmpty(new ReportAnnualDto { Year = all.Year, Status = all.Status, Count = 0 }))
.SelectMany(group => group)
.OrderBy(u => u.Year)
.ToList();
return result;
}
public class Order
{
public int Id { get; set; }
[Required]
public DateTime OrderDateTime { get; set; }
[Required]
[MaxLength(250)]
public int CustomerId { get; set; }
public string Status { get; set; }
[MaxLength(50)]
public string DoneBy { get; set; }
public List<OrderDetail> OrderDetails { get; set; }
public Customer Customer { get; set; }
}
public class OrderDetail
{
public int Id { get; set; }
[Required]
[MaxLength(100)]
public string ProductCode { get; set; }
[MaxLength(250)]
public string? ProductName { get; set; }
[Required]
public int Quantity { get; set; }
[Required]
public double BuyUnitPrice { get; set; }
public double CostRatio { get; set; }
public double UnitCost { get; set; }
public double TotalBuyPrice { get; set; }
public double? SellUnitPrice { get; set; }
public double? TotalSellPrice { get; set; }
[MaxLength(150)]
public string? ShippingNumber { get; set; }
public string? Status { get; set; }
[MaxLength(150)]
public string? TrackingNumber { get; set; }
[MaxLength(400)]
public string? Description { get; set; }
public string? Currency { get; set; }
public string? CustomerStockCode { get; set; }
public string? CustomerOrderNumber { get; set; }
public int IsActive { get; set; }
public double? TotalUnitCost { get; set; }
public int OrderId { get; set; }
public int VendorId { get; set; }
public string? Warehouse { get; set; }
public string? PaymentStatus { get; set; }
public Order Order { get; set; }
public Vendor Vendor { get; set; }
[DataType(DataType.DateTime)]
public DateTime? CompletionDateTime { get; set; }
public int? ShippingWeek { get; set; }
public string? PoNotes { get; set; }
}