Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 52 additions & 3 deletions aspnetcore/blazor/blazor-ef-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ For Microsoft Azure services, we recommend using *managed identities*. Managed i

The sample app was built as a reference for server-side Blazor apps that use EF Core. The sample app includes a grid with sorting and filtering, delete, add, and update operations.

The sample demonstrates use of EF Core to handle optimistic concurrency. However, [native database-generated concurrency tokens](/ef/core/saving/concurrency?tabs=fluent-api#native-database-generated-concurrency-tokens) aren't supported for SQLite databases, which is the database provider for the sample app. To demonstrate concurrency with the sample app, adopt a different database provider that supports database-generated concurrency tokens (for example, the [SQL Server provider](/ef/core/providers/sql-server)).

:::moniker range=">= aspnetcore-8.0"

[View or download sample code](https://github.com/dotnet/blazor-samples) ([how to download](xref:blazor/fundamentals/index#sample-apps)): Select the folder that matches the version of .NET that you're adopting. Within the version folder, access the sample named `BlazorWebAppEFCore`.
Expand All @@ -60,7 +58,58 @@ The sample demonstrates use of EF Core to handle optimistic concurrency. However

:::moniker-end

The sample uses a local [SQLite](https://www.sqlite.org/index.html) database so that it can be used on any platform. The sample also configures database logging to show the SQL queries that are generated. This is configured in `appsettings.Development.json`:
### Use the sample with SQLite

The sample uses a local [SQLite](https://www.sqlite.org/index.html) database so that it can be used on any platform.

The sample demonstrates use of EF Core to handle optimistic concurrency. However, [native database-generated concurrency tokens](/ef/core/saving/concurrency?tabs=fluent-api#native-database-generated-concurrency-tokens) aren't supported for SQLite databases, which is the database provider for the sample app. To demonstrate concurrency with the sample app, adopt a different database provider that supports database-generated concurrency tokens (for example, the [SQL Server provider](/ef/core/providers/sql-server)). You can adopt SQL Server for the sample app by following the guidance in the next section, *Use the sample with SQL Server and optimistic concurrency*.

### Use the sample with SQL Server and optimistic concurrency

The sample demonstrates use of EF Core to handle optimistic concurrency but only for a database provider that uses [native database-generated concurrency tokens](/ef/core/saving/concurrency?tabs=fluent-api#native-database-generated-concurrency-tokens), which is a feature supported for SQL Server. To demonstrate concurrency with the sample app, the sample app can be converted from the SQLite provider to use the [SQL Server provider](/ef/core/providers/sql-server) with a new SQL Server database created using .NET scaffolding.

Use the following guidance to adopt SQL Server for the sample app using Visual Studio.

Open the `Program` file (`Program.cs`) and comment out the lines that add the database context factory with the SQLite provider:

```diff
- builder.Services.AddDbContextFactory<ContactContext>(opt =>
- opt.UseSqlite($"Data Source={nameof(ContactContext.ContactsDb)}.db"));
+ //builder.Services.AddDbContextFactory<ContactContext>(opt =>
+ // opt.UseSqlite($"Data Source={nameof(ContactContext.ContactsDb)}.db"));
```

Save the `Program.cs` file.

Right-click the project in **Solution Explorer** and select **Add** > **New Scaffolded Item**.

In the **Add New Scaffolded Item** dialog, select **Installed** > **Common** > **Blazor** > **Razor Component** > **Razor Components Using Entity Framework (CRUD)**. Select the **Add** button.

In the **Add Razor Components Using Entity Framework (CRUD)** dialog, use the following settings:

* **Template**: Use the default selection (**CRUD**).
* **Model class**: Select the `Contact` model from the dropdown list.
* **DbContext class**: Select the plus sign (`+`) and select **Add** using the default context class name generated by the scaffolder.
* **Database provider**: Use the default selection (**SQL Server**).

Select **Add** to scaffold the model and create the SQL Server database.

When the scaffolding operation completes, delete the generated context class from the `Data` folder (`Data/{PROJECT NAME}Context.cs`, where the `{PROJECT NAME}` placeholder is the project's name/namespace).

Delete the `ContactPages` folder from the `Components/Pages` folder, which contains [QuickGrid](xref:blazor/components/quickgrid)-based pages for contact management. For a complete demonstration of QuickGrid-based pages for managing data, use the <xref:blazor/tutorials/movie-database-app/index> tutorial.

Open the `Program` file (`Program.cs`) and find the line that scaffolding added to create a database context factory using the SQL Server provider. Change the context from the generated context class (deleted earlier) to the app's existing `ContactContext` class:

```diff
- builder.Services.AddDbContextFactory<BlazorWebAppEFCoreContext>(options =>
+ builder.Services.AddDbContextFactory<ContactContext>(options =>
```

At this point, the app is using the SQL Server provider and a SQL Server database created for the `Contact` model class. Optimistic concurrency works using [native database-generated concurrency tokens](/ef/core/saving/concurrency?tabs=fluent-api#native-database-generated-concurrency-tokens) that are already implemented in the sample app's `ContactContext` class.

### Database logging

The sample also configures database logging to show the SQL queries that are generated. This is configured in `appsettings.Development.json`:

:::moniker range=">= aspnetcore-9.0"

Expand Down
Loading