Поделиться через


Blazor Создайте приложение для базы данных фильмов (часть 4 - Работа с базой данных)

Примечание.

Это не последняя версия этой статьи. В текущем выпуске ознакомьтесь с версией этой статьи .NET 9.

Внимание

Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

В текущем выпуске смотрите версию этой статьи .NET 9.

Эта статья является четвертой частью Blazor учебника по приложению базы данных фильма, которое учит вас основам создания ASP.NET Core Blazor Web App с функциями управления базой данных фильмов.

В этой части серии учебников основное внимание уделяется контексту базы данных и непосредственному работе со схемой и данными базы данных. Заполнение базы данных данными также рассматривается.

Безопасный поток проверки подлинности, необходимый для рабочих приложений

В этом руководстве используется локальная база данных, которая не требует проверки подлинности пользователя. Рабочие приложения должны использовать самый безопасный поток проверки подлинности. Дополнительные сведения о проверке подлинности для развернутых тестов и рабочих Blazor Web Appсред см. в следующих ресурсах:

Для служб Microsoft Azure рекомендуется использовать управляемые удостоверения. Управляемые удостоверения безопасно проходят проверку подлинности в службах Azure без хранения учетных данных в коде приложения. Дополнительные сведения см. на следующих ресурсах:

Контекст базы данных

Контекст BlazorWebAppMoviesContextбазы данных, подключается к базе данных и сопоставляет объекты модели с записями базы данных. Контекст базы данных был создан во второй части этой серии. Появившийся в Program файле код сгенерированного контекста базы данных.

builder.Services.AddDbContextFactory<BlazorWebAppMoviesContext>(options =>
    options.UseSqlServer(
        builder.Configuration.GetConnectionString("BlazorWebAppMoviesContext") ?? 
        throw new InvalidOperationException(
            "Connection string 'BlazorWebAppMoviesContext' not found.")));
builder.Services.AddDbContextFactory<BlazorWebAppMoviesContext>(options =>
    options.UseSqlite(
        builder.Configuration.GetConnectionString("BlazorWebAppMoviesContext") ?? 
        throw new InvalidOperationException(
            "Connection string 'BlazorWebAppMoviesContext' not found.")));
builder.Services.AddDbContextFactory<BlazorWebAppMoviesContext>(options =>
    options.UseSqlite(
        builder.Configuration.GetConnectionString("BlazorWebAppMoviesContext") ?? 
        throw new InvalidOperationException(
            "Connection string 'BlazorWebAppMoviesContext' not found.")));

AddDbContextFactory регистрирует фабрику для заданного контекста как службу в коллекции служб приложения.

UseSqlServer или UseSqlite настраивает контекст для подключения к базе данных Microsoft SQL Server или SQLite. Другие поставщики доступны для подключения к дополнительным типам баз данных.

GetConnectionString использует систему конфигурации ASP.NET Core для чтения ключа ConnectionStrings для имени строки подключения, которое указано в предыдущем примере, BlazorWebAppMoviesContext.

Для локальной разработки конфигурация получает строку подключения к базе данных из файла параметров приложения (appsettings.json). Заполнитель {CONNECTION STRING} в следующем примере — это строка подключения:

"ConnectionStrings": {
  "BlazorWebAppMoviesContext": "{CONNECTION STRING}"
}

Ниже приведен пример строки подключения:

Server=(localdb)\mssqllocaldb;Database=BlazorWebAppMoviesContext-00001111-aaaa-2222-bbbb-3333cccc4444;Trusted_Connection=True;MultipleActiveResultSets=true

Когда приложение развертывается на тестовом или рабочем сервере, строку подключения безопасно храните вне файлов конфигурации проекта.

Предупреждение

Не сохраняйте секреты приложений, строка подключения, учетные данные, пароли, персональные идентификационные номера (ПИН-коды), частный код C#/.NET или закрытые ключи и токены в клиентском коде, который всегда небезопасн. В тестовой, промежуточной и рабочей средах серверный Blazor код и веб-API должны использовать безопасные потоки проверки подлинности, которые не сохраняют учетные данные в файлах кода проекта или конфигурации. Вне локального тестирования разработки рекомендуется избегать использования переменных среды для хранения конфиденциальных данных, так как переменные среды не являются наиболее безопасным подходом. Для локального тестирования разработки средство Secret Manager рекомендуется для защиты конфиденциальных данных. Дополнительные сведения см. в разделе "Безопасное обслуживание конфиденциальных данных и учетных данных".

Технология базы данных

В версии этого руководства Visual Studio используется SQL Server.

SQL Server Express LocalDB — это упрощенная версия ядра СУБД SQL Server Express, предназначенная для разработки программ. LocalDB запускается по запросу в пользовательском режиме, поэтому настройки не слишком сложны. Файлы базы данных Master (*.mdf) размещаются в каталоге C:/Users/{USER}, где {USER} является плейсхолдером идентификатора пользователя системы.

В меню Вид откройте обозреватель объектов SQL Server (SSOX).

Меню

Щелкните правой кнопкой мыши таблицу Movie и выберите пункт Конструктор представлений:

Контекстные меню для открытия таблицы

Откроется конструктор представлений:

Таблица

Обратите внимание на значок с изображением ключа рядом с ID. EF создает свойство первичного ключа с именем ID.

Щелкните правой кнопкой мыши таблицу Movie и выберите пункт Просмотреть данные:

Контекстные меню для открытия данных таблицы

Данные таблицы открываются на новой вкладке в Visual Studio:

Таблица фильмов открыта, показ данных таблицы фильмов

Версия VS Code этого руководства использует SQLite, которая является общедоступным, автономным, полнофункциональный ядром СУБД SQL.

Существует множество сторонних средств, которые можно использовать для управления базами данных SQLite и просмотра. На следующем рисунке показан браузер БАЗЫ данных для SQLite:

DB Browser для SQLite, показывающий базу данных фильмов

В этом руководстве EF Core используются миграции. Миграция обновляет схему базы данных в соответствии с изменениями в модели данных. Однако миграции могут вносить изменения только в базу данных, которую EF Core поддерживает поставщик. Ресурсы перечислены в конце этой статьи для дальнейшего чтения.

Версия VS Code этого руководства использует SQLite, которая является общедоступным, автономным, полнофункциональный ядром СУБД SQL.

Существует множество сторонних средств, которые можно использовать для управления базами данных SQLite и просмотра. На следующем рисунке показан браузер БАЗЫ данных для SQLite:

DB Browser для SQLite с базой данных фильмов

В этом руководстве используются миграции EF Core. Миграция обновляет схему базы данных в соответствии с изменениями в модели данных. Однако миграции могут вносить изменения только в базу данных, которую EF Core поддерживает поставщик. Ресурсы перечислены в конце этой статьи для дальнейшего чтения.

Заполнение базы данных

Начальный код может создать набор записей для тестирования разработки или даже использовать для создания исходных данных для новой рабочей базы данных.

В папке Data создайте класс с именем SeedData следующего кода.

Data/SeedData.cs:

using Microsoft.EntityFrameworkCore;
using BlazorWebAppMovies.Models;

namespace BlazorWebAppMovies.Data;

public class SeedData
{
    public static void Initialize(IServiceProvider serviceProvider)
    {
        using var context = new BlazorWebAppMoviesContext(
            serviceProvider.GetRequiredService<
                DbContextOptions<BlazorWebAppMoviesContext>>());

        if (context == null || context.Movie == null)
        {
            throw new NullReferenceException(
                "Null BlazorWebAppMoviesContext or Movie DbSet");
        }

        if (context.Movie.Any())
        {
            return;
        }

        context.Movie.AddRange(
            new Movie
            {
                Title = "Mad Max",
                ReleaseDate = new DateOnly(1979, 4, 12),
                Genre = "Sci-fi (Cyberpunk)",
                Price = 2.51M,
            },
            new Movie
            {
                Title = "The Road Warrior",
                ReleaseDate = new DateOnly(1981, 12, 24),
                Genre = "Sci-fi (Cyberpunk)",
                Price = 2.78M,
            },
            new Movie
            {
                Title = "Mad Max: Beyond Thunderdome",
                ReleaseDate = new DateOnly(1985, 7, 10),
                Genre = "Sci-fi (Cyberpunk)",
                Price = 3.55M,
            },
            new Movie
            {
                Title = "Mad Max: Fury Road",
                ReleaseDate = new DateOnly(2015, 5, 15),
                Genre = "Sci-fi (Cyberpunk)",
                Price = 8.43M,
            },
            new Movie
            {
                Title = "Furiosa: A Mad Max Saga",
                ReleaseDate = new DateOnly(2024, 5, 24),
                Genre = "Sci-fi (Cyberpunk)",
                Price = 13.49M,
            });

        context.SaveChanges();
    }
}

Экземпляр контекста базы данных получен из контейнера DI (внедрения зависимостей). Если фильмы присутствуют, вызывается return, чтобы избежать заполнения базы данных. Когда база данных пуста, фильмы франшизы Mad MaxWarner Bros. Entertainment) добавляются.

Чтобы выполнить инициализатор, добавьте следующий код Program в файл сразу после строки, создающей приложение (var app = builder.Build();). Инструкция using гарантирует, что контекст базы данных удаляется после завершения операции заполнения.

using (var scope = app.Services.CreateScope())
{
    var services = scope.ServiceProvider;

    SeedData.Initialize(services);
}

Если база данных содержит записи из предыдущего тестирования, запустите приложение и удалите сущности, созданные в базе данных. Остановите приложение, закрыв окно браузера.

Если база данных содержит записи из предыдущего тестирования, запустите приложение и удалите сущности, созданные в базе данных. Остановите приложение, закрыв окно браузера и нажав клавиши SHIFT+F5 на клавиатуре в VS Code.

Если база данных содержит записи из предыдущего тестирования, запустите приложение и удалите сущности, созданные в базе данных. Остановите приложение, закрыв окно браузера и нажав клавиши CTRL+C (Windows) в командной оболочке.

Когда база данных пуста, запустите приложение.

Перейдите на страницу фильмов Index, чтобы увидеть предложенные фильмы.

Страница индекса фильмов с списком фильмов Mad Max после заполнения базы данных

Привязка формы к модели

Просмотрите компонент Edit (Components/Pages/MoviePages/Edit.razor).

При выполнении HTTP-запроса GET для Edit страницы компонента (например, на относительном URL-адресе: /movies/edit?id=6):

  • Метод OnInitializedAsync извлекает фильм с Id6 из базы данных и назначает его свойству Movie.
  • Параметр EditForm.Model задает объект модели верхнего уровня для формы. Контекст редактирования создается для формы с помощью назначенной модели.
  • Форма отображается со значениями из фильма.

Edit При публикации страницы на сервере значения формы на странице привязаны к Movie свойству, так как [SupplyParameterFromForm] атрибут аннотирован в свойствеMovie:

[SupplyParameterFromForm]
private Movie? Movie { get; set; }

Если состояние модели содержит ошибки при отправке формы, например, если ReleaseDate не удается преобразовать в дату, форма будет заново отображена с отправленными значениями. Если ошибки модели отсутствуют, фильм сохраняется с помощью опубликованных значений формы.

Обработка исключений параллелизма

Просмотрите метод Edit компонента UpdateMovie (Components/Pages/MoviePages/Edit.razor):

private async Task UpdateMovie()
{
    using var context = DbFactory.CreateDbContext();
    context.Attach(Movie!).State = EntityState.Modified;

    try
    {
        await context.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!MovieExists(Movie!.Id))
        {
            NavigationManager.NavigateTo("notfound");
        }
        else
        {
            throw;
        }
    }

    NavigationManager.NavigateTo("/movies");
}

Исключения параллелизма обнаруживаются, когда один клиент удаляет фильм, а другой клиент публикует изменения в фильме.

Чтобы проверить, как параллелизм обрабатывается предыдущим кодом:

  1. Выберите Edit для фильма, внесите изменения, но не выбирайте Save.
  2. В другом окне браузера откройте приложение на страницу фильма Index и выберите Delete ссылку для того же фильма, чтобы удалить фильм.
  3. В предыдущем окне браузера внесите изменения в фильм, нажав Save кнопку.
  4. Браузер переходит к конечной notfound точке, которая не существует и дает результат 404 (не найден).

Дополнительные рекомендации по обработке параллелизма с EF Core в приложениях Blazor доступны в документации Blazor.

Остановка приложения

Если приложение запущено, закройте приложение, закрыв окно браузера.

Если приложение запущено, закройте приложение, закрыв окно браузера и нажав клавиши SHIFT+F5 на клавиатуре в VS Code.

Если приложение запущено, закройте приложение, закрыв окно браузера и нажав клавиши CTRL+C в командной оболочке.

Устранение неполадок с использованием готового образца

Если при выполнении руководства вы столкнулись с проблемой, которую невозможно решить только при помощи текста, сравните свой код с завершенным проектом в репозитории с примерами: Blazor.

Примеры в репозитории GitHub Blazor (dotnet/blazor-samples)

Выберите последнюю папку версии. Пример папки для проекта этого руководства называется BlazorWebAppMovies.

Дополнительные ресурсы

Mad Max, The Road Warrior, Mad Max: Beyond Thunderdome, Mad Max: Fury Road, и Furiosa: Mad Max Saga являются товарными знаками и авторскими правами Warner Bros. Развлечения.

Следующие шаги