I am using EF Core 5.0 and have the following code:
public async IAsyncEnumerable<Item> GetItems([EnumeratorCancellation] CancellationToken cancellationToken = default)
{
await using var ctx = _DbContextFunc();
//Isolationlevel is required to not cause any issues with parallel working on already read items
await ctx.Database.BeginTransactionAsync(IsolationLevel.ReadUncommitted, cancellationToken).ConfigureAwait(false);
await foreach (var item in ctx.Item.
.AsSplitQuery()
.Include(i => i.ItemDetail1)
.Include(i => i.ItemDetail2)
.OrderByDescending(i => i.ItemId)
.AsNoTracking()
.AsAsyncEnumerable()
.WithCancellation(cancellationToken))
{
yield return item;
}
}
It works as expected allowing me to populate a datagrid while more data is still loaded. If I cancel the provided CancelationToken, first I get a TaskCanceledException on the line MoveNextAsync() which is expected.
BUT: I can see in SQL Profiler that the SQL query itself is not aborted but always runs until all data is loaded and only then I get a second TaskCanceledException on that same line.
How do I abort the query itself?
Update
I added the AsSplitQuery() to the sample as it turned out to be the reason for the behavior I experienced (as Ivan rightly guessed). Had left it out to make the sample shorter...