Skip to content

11 Queries parallelization

Matthieu MEZIL (MSFT) edited this page Jun 6, 2015 · 1 revision

In the CustomerWindowViewModel, we have this method:

private async Task LoadAsync(string customerId)
{
    Customer = await _context.Customers.AsAsyncQueryable().FirstOrDefault(c => c.Id == customerId).IncludeOrdersWithExpression(orders => orders.IncludeOrderDetails().WithHasInvoice()).ExecuteAsync();
    await _context.Products.AsAsyncQueryable().Select(p => new Product { Id = p.Id, FullName = p.FullName }).ExecuteAsync();
}

It works fine but it is useless to wait to got the Customer before getting the products.

We should be able to do both in parallel.

We can do this:

private async Task LoadAsync(string customerId)
{
    var customerTask = _context.Customers.AsAsyncQueryable().FirstOrDefault(c => c.Id == customerId).IncludeOrdersWithExpression(orders => orders.IncludeOrderDetails().WithHasInvoice()).ExecuteAsync();
    await _context.Products.AsAsyncQueryable().Select(p => new Product { Id = p.Id, FullName = p.FullName }).ExecuteAsync();
    Customer = await customerTask;
}

But the problem here is the fact that it is not a good idea to have many calls to the server.

So WAQS proposes a way to group queries in one call:

private async Task LoadAsync(string customerId)
{
    var customerAndProducts = await _context.ExecuteQueriesAsync(
        _context.Customers.AsAsyncQueryable().FirstOrDefault(c => c.Id == customerId).IncludeOrdersWithExpression(orders => orders.IncludeOrderDetails().WithHasInvoice()),
        _context.Products.AsAsyncQueryable().Select(p => new Product { Id = p.Id, FullName = p.FullName }));
    Customer = (Customer)customerAndProducts[0];
}

As always, you can download the result here.

Clone this wiki locally