I have the following linq statements which I am hoping to cut down from multiple round trips to my database to one using subquery.
This is my code before refactoring:
IQueryable<Customers> customers= this.BaseQuery.Where(o => o.EmailAddress == emailAddress);
int totalCustomersCount = await customers.CountAsync();
int totalDisabledCustomersCount = await customers.Where(o => CustomerState.Disabled == o.CurrentState).CountAsync();
int totalCancelledCustomersCount = await customers.Where(o => CustomerState.Cancelled == o.CurrentState).CountAsync();
int totalExpiredCustomersCount = await customers.Where(o => CustomerState.Archived == o.CurrentState).CountAsync();
int totalPremiumCustomerCount = await customers.Where(o => CustomerState.Premium== o.CurrentState).CountAsync();
CustomerStatistics customerStatistics = new CustomerStatistics()
{
TotalCustomersCount = totalCustomersCount,
TotalDisabledCustomersCount = totalDisabledCustomersCount,
TotalCancelledCustomersCount = totalCancelledCustomersCount,
TotalExpiredCustomersCount= totalExpiredCustomersCount,
TotalPremiumCustomerCount= totalPremiumCustomerCount,
};
and I have reworked this code to look like this
IQueryable<Customers>? query = this.Context.Customers.Where(o => o.EmailAddress == emailAddress);
IQueryable<CustomerStatistics >? myQuery= query.Select(o => new CustomerStatistics()
{
TotalCustomersCount = query.Count(),
TotalDisabledCustomersCount = query.Where(o => o.CurrentState == CustomerState.Disabled).Count(),
TotalCancelledCustomersCount = query.Where(o => o.CurrentState == CustomerState.Cancelled).Count(),
TotalExpiredCustomersCount= query.Where(o => o.CurrentState == CustomerState.Archived).Count(),
TotalPremiumCustomerCount= query.Where(o => o.CurrentState == CustomerState.Premium).Count(),
});
Is this along the right lines? To me, it still looks like it will be makign round trips to the database to get each count.
Update to the example query:
IQueryable<Order> orders = this.BaseQuery.Where(o => o.CustomerContactId == customerContactId);
int totalOrderCount = await orders.CountAsync();
int totalInProgressOrderCount = await orders.Where(o => OrderState.Fulfilment == o.CurrentState).CountAsync();
int totalCancelledOrderCount = await orders.Where(o => OrderState.Cancelled == o.CurrentState).CountAsync();
int totalExpiredOrderCount = await orders.Where(o => OrderState.Archived == o.CurrentState).CountAsync();
int totalQuoteCount = await orders.Where(o => OrderState.Initial == o.CurrentState || OrderState.QuoteIssued == o.CurrentState || OrderState.ReadyToPlace == o.CurrentState || OrderState.CheckGeometry == o.CurrentState).CountAsync();
int totalIssuedOrderCount = await orders.Where(o => OrderState.QuoteIssued == o.CurrentState).CountAsync();
CustomerContactOrderStatistics customerContactOrderStatistics = new CustomerContactOrderStatistics()
{
TotalOrderCount = totalOrderCount,
TotalInProgressOrderCount = totalInProgressOrderCount,
TotalCancelledOrderCount = totalCancelledOrderCount,
TotalExpiredOrderCount = totalExpiredOrderCount,
TotalQuoteCount = totalQuoteCount,
TotalIssuedOrderCount = totalIssuedOrderCount,
};