.ToListAsync<T>(Summary)
Async version of .ToList<T>(Summary). On an EF Core query it counts the groups with EF Core's CountAsync() and reads them with EF Core's ToListAsync(). Since 3.2.0 two more overloads take a CancellationToken, which reaches both.
DwCaps.MinGroupSize ships on, at 5, so a guarded summary removes every group with fewer than five rows — not refused, and nothing in the answer says a group was dropped. That is right for anonymised reporting and surprising for an operational count. Set Caps.MinGroupSize = 1 to switch the floor off, deliberately. An unguarded call is never floored. See k-anonymity.Signature
public static Task<SummaryResult> ToListAsync<T>(
this IQueryable<T> query,
Summary summary,
bool getQueryString = false)
where T : class
// 3.2.0
public static Task<SummaryResult> ToListAsync<T>(
this IQueryable<T> query,
Summary summary,
CancellationToken cancellationToken)
where T : class
public static Task<SummaryResult> ToListAsync<T>(
this IQueryable<T> query,
Summary summary,
bool getQueryString,
CancellationToken cancellationToken)
where T : class| Parameter | Type | Default | Description |
|---|---|---|---|
summary | Summary | – | Composition object |
getQueryString | bool | false | When true, captures the generated SQL on SummaryResult.QueryString |
cancellationToken | CancellationToken | – | Cancels the count and the read. The overload without it passes CancellationToken.None |
Pipeline
Whereapplied on the typed query.Groupapplied — produces grouped dynamic intermediate.Havingapplied — fields must reference aggregate aliases.- The grouped query is counted →
TotalCount. On an EF Core query this is EF Core'sCountAsync(cancellationToken). Orderapplied on the grouped query.Pageapplied on the grouped query.- Async materialization as
List<dynamic>. On an EF Core query this is EF Core'sToListAsync(cancellationToken).
A source whose provider is not EF Core's — rows in memory through AsQueryable(), for one — keeps the reads it had in 3.1: a synchronous Count(), then Dynamic LINQ's ToDynamicListAsync(), which reads on the calling thread. A token that is already canceled still stops it before the count.
ToDynamicListAsync(), which had no token to pass on, on every provider. On an EF Core query both now run through EF Core's asynchronous operators, so a canceled token reaches the database. The count and the rows are the same.GroupBy fields like Category.Name become flattened aliases in the result (e.g., CategoryName). Order fields in Summary.Orders use the dotted form — the library handles alias mapping internally.Cancellation
The two overloads that take a CancellationToken are new in 3.2.0. The token reaches the count and the read. On an EF Core query a canceled token stops whichever of the two is running, and the call throws OperationCanceledException. EF Core's TaskCanceledException derives from it. The overload without a token passes CancellationToken.None.
They are overloads, not an optional parameter added to the old signature. The 3.1 signature is unchanged, so code compiled against 3.1 still binds. The guarded handle that ApplyPolicy returns has the same overloads.
default fits both bool getQueryString and CancellationToken, so the compiler reports the call as ambiguous (CS0121). Write false, a token, or a named argument.await db.Products.ToListAsync(summary, default); // CS0121: ambiguous
await db.Products.ToListAsync(summary, cancellationToken); // the token overload
await db.Products.ToListAsync(summary, true, cancellationToken); // the SQL and a tokenReturns
Task<SummaryResult>.
Example
SummaryResult result = await dbContext.Products.ToListAsync(summary);
foreach (var row in result.Data)
{
Console.WriteLine($"{row.CategoryName}: {row.ProductCount} products");
}ASP.NET Core endpoint.
app.MapPost("/products/summary", async (Summary summary, AppDbContext db) =>
{
var result = await db.Products.ToListAsync(summary);
return Results.Ok(result);
});{
"pageNumber": 1,
"pageSize": 10,
"pageCount": 1,
"totalCount": 3,
"data": [
{ "CategoryName": "Electronics", "ProductCount": 15, "AvgPrice": 349.99, "TotalRevenue": 5249.85 }
],
"queryString": null
}See also
.ToList<T>(Summary)— synchronous variant (and in-memory overload)..Summary<T>— non-materializing composition.- JSON Cookbook: Summary.