Skip to content

Commit 308e484

Browse files
authored
Merge pull request #34889 from dotnet/main
2 parents 6f5fd10 + 0639f2e commit 308e484

5 files changed

Lines changed: 103 additions & 9 deletions

File tree

aspnetcore/blazor/components/quickgrid.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,3 +567,94 @@ dotnet aspnet-codegenerator blazor -h
567567
---
568568

569569
For an example use of the QuickGrid scaffolder, see <xref:blazor/tutorials/movie-database-app/index>.
570+
571+
<!-- UPDATE 10.0 - PU work tracked by https://github.com/dotnet/aspnetcore/issues/58716.
572+
Versioning out at 10.0 for now. -->
573+
574+
:::moniker range="< aspnetcore-10.0"
575+
576+
## Multiple concurrent EF Core queries trigger `System.InvalidOperationException`
577+
578+
Multiple concurrent EF Core queries can trigger the following <xref:System.InvalidOperationException?displayProperty=fullName>:
579+
580+
> :::no-loc text="System.InvalidOperationException: A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.":::
581+
582+
This scenario is scheduled for improvement in an upcoming release of ASP.NET Core. For more information, see [[Blazor] Improve the experience with QuickGrid and EF Core (`dotnet/aspnetcore` #58716)](https://github.com/dotnet/aspnetcore/issues/58716).
583+
584+
In the meantime, you can address the problem using an <xref:Microsoft.AspNetCore.Components.QuickGrid.QuickGrid%601.ItemsProvider%2A> with a cancellation token. The cancellation token prevents concurrent queries by cancelling the previous request when a new request is issued.
585+
586+
Consider the following example, which is based on the movie database `Index` component for the <xref:blazor/tutorials/movie-database-app/index> tutorial. The simpler version scaffolded into the app can be seen in the article's [sample app](xref:blazor/tutorials/movie-database-app/index#sample-app). The `Index` component scaffolded into the app is replaced by the following component.
587+
588+
`Components/Pages/MoviePages/Index.razor`:
589+
590+
```razor
591+
@page "/movies"
592+
@rendermode InteractiveServer
593+
@using Microsoft.EntityFrameworkCore
594+
@using Microsoft.AspNetCore.Components.QuickGrid
595+
@using BlazorWebAppMovies.Models
596+
@using BlazorWebAppMovies.Data
597+
@inject IDbContextFactory<BlazorWebAppMovies.Data.BlazorWebAppMoviesContext> DbFactory
598+
599+
<PageTitle>Index</PageTitle>
600+
601+
<h1>Index</h1>
602+
603+
<div>
604+
<input type="search" @bind="titleFilter" @bind:event="oninput" />
605+
</div>
606+
607+
<p>
608+
<a href="movies/create">Create New</a>
609+
</p>
610+
611+
<div>
612+
<QuickGrid Class="table" TGridItem="Movie" ItemsProvider="GetMovies"
613+
ItemKey="(x => x.Id)" Pagination="pagination">
614+
<PropertyColumn Property="movie => movie.Title" Sortable="true" />
615+
<PropertyColumn Property="movie => movie.ReleaseDate" Title="Release Date" />
616+
<PropertyColumn Property="movie => movie.Genre" />
617+
<PropertyColumn Property="movie => movie.Price" />
618+
<PropertyColumn Property="movie => movie.Rating" />
619+
620+
<TemplateColumn Context="movie">
621+
<a href="@($"movies/edit?id={movie.Id}")">Edit</a> |
622+
<a href="@($"movies/details?id={movie.Id}")">Details</a> |
623+
<a href="@($"movies/delete?id={movie.Id}")">Delete</a>
624+
</TemplateColumn>
625+
</QuickGrid>
626+
</div>
627+
628+
<Paginator State="pagination" />
629+
630+
@code {
631+
private BlazorWebAppMoviesContext context = default!;
632+
private PaginationState pagination = new PaginationState { ItemsPerPage = 5 };
633+
private string titleFilter = string.Empty;
634+
635+
public async ValueTask<GridItemsProviderResult<Movie>> GetMovies(GridItemsProviderRequest<Movie> request)
636+
{
637+
using var context = DbFactory.CreateDbContext();
638+
var totalCount = await context.Movie.CountAsync(request.CancellationToken);
639+
IQueryable<Movie> query = context.Movie.OrderBy(x => x.Id);
640+
query = request.ApplySorting(query).Skip(request.StartIndex);
641+
642+
if (request.Count.HasValue)
643+
{
644+
query = query.Take(request.Count.Value);
645+
}
646+
647+
var items = await query.ToArrayAsync(request.CancellationToken);
648+
649+
var result = new GridItemsProviderResult<Movie>
650+
{
651+
Items = items,
652+
TotalItemCount = totalCount
653+
};
654+
655+
return result;
656+
}
657+
}
658+
```
659+
660+
:::moniker-end

aspnetcore/blazor/tutorials/movie-database-app/part-2.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -468,22 +468,25 @@ Add a movie to the database. In the following example, the classic sci-fi movie
468468

469469
When you select the **:::no-loc text="Create":::** button, the movie data is posted to the server and saved in the database.
470470

471-
:::moniker range=">= aspnetcore-9.0"
472-
473-
<!-- UPDATE 10.0 Revert when https://github.com/dotnet/aspnetcore/issues/53996 is addressed -->
471+
:::moniker range=">= aspnetcore-9.0 < aspnetcore-10.0"
474472

475473
:::zone pivot="vs"
476474

477-
A Visual Studio debugger regression breaks with a <xref:Microsoft.AspNetCore.Components.NavigationException> on the line that navigates back to the `Index` page:
475+
In .NET 9, the Visual Studio debugger may break with a <xref:Microsoft.AspNetCore.Components.NavigationException> on the line that navigates back to the `Index` page:
478476

479477
![Debugger regression: A navigation exception is thrown on the NavigateTo call.](~/blazor/tutorials/movie-database-app/part-2/_static/debugger_regression.png)
480478

481-
To resolve this problem until the debugger is updated by a future Visual Studio release:
479+
To resolve this problem:
482480

483481
1. Deselect the checkbox for **Break when this exception type is user-handled**.
484482
2. Select the **Continue** button in the menu bar to continue execution.
485483

486-
The exception won't be thrown when the <xref:Microsoft.AspNetCore.Components.NavigationManager.NavigateTo%2A> method is executed throughout the rest of the tutorial series.
484+
The exception isn't thrown when a <xref:Microsoft.AspNetCore.Components.NavigationManager.NavigateTo%2A> method is executed throughout the rest of the tutorial series.
485+
486+
In .NET 10 or later:
487+
488+
* Updates to the way that <xref:Microsoft.AspNetCore.Components.NavigationManager.NavigateTo%2A> manages navigation never result in a <xref:Microsoft.AspNetCore.Components.NavigationException>.
489+
* The Visual Studio debugger doesn't break when processing <xref:Microsoft.AspNetCore.Components.NavigationManager.NavigateTo%2A> calls with a valid endpoint.
487490

488491
:::zone-end
489492

aspnetcore/release-notes/aspnetcore-10.0.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ author: rick-anderson
44
description: Learn about the new features in ASP.NET Core 10.0.
55
ms.author: riande
66
ms.custom: mvc
7-
ms.date: 2/12/2025
7+
ms.date: 3/5/2025
88
uid: aspnetcore-10
99
---
1010
# What's new in ASP.NET Core 10.0
-139 KB
Loading

aspnetcore/release-notes/aspnetcore-10/includes/blazor.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Apply a stylesheet class to a row of the grid based on the row item using the ne
1515

1616
For more information, see <xref:blazor/components/quickgrid?view=aspnetcore-10.0#style-a-table-row-based-on-the-row-item>.
1717

18-
### Blazor script
18+
### Blazor script as static web asset
1919

2020
In prior releases of .NET, the Blazor script is served from an embedded resource in the ASP.NET Core shared framework. In .NET 10 or later, the Blazor script is served as a static web asset with automatic compression and fingerprinting.
2121

@@ -28,7 +28,7 @@ For more information, see the following resources:
2828

2929
The [`[Route]` attribute](xref:Microsoft.AspNetCore.Components.RouteAttribute) now supports route syntax highlighting to help visualize the structure of the route template:
3030

31-
![Route template pattern for the Order ID is highlighted in a method that maps endpoints](~/release-notes/aspnetcore-10/_static/route-template-highlighting.png)
31+
![Route template pattern of a route attribute for the movie entity ID shows syntax highlighting](~/release-notes/aspnetcore-10/_static/route-template-highlighting.png)
3232

3333
<!-- PREVIEW 2
3434

0 commit comments

Comments
 (0)