Часть 4 серии руководств по Razor Pages

Примечание.

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

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

Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в статье о политике поддержки .NET и .NET Core. В текущем выпуске см . версию .NET 8 этой статьи.

Внимание

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

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

Джо Одетт

Объект RazorPagesMovieContext обрабатывает задачу подключения к базе данных и сопоставления объектов Movie с записями базы данных. Контекст базы данных регистрируется с помощью контейнера внедрения зависимостей в файле Program.cs:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RazorPagesMovie.Data;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));

Система конфигурации ASP.NET Core считывает ключ ConnectionString. Для разработки на локальном уровне конфигурация получает строку подключения из файла appsettings.json.

Созданная строка подключения выглядит аналогично следующему коду JSON.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "RazorPagesMovieContext": "Server=(localdb)\\mssqllocaldb;Database=RazorPagesMovieContext-f2e0482c-952d-4b1c-afe9-a1a3dfe52e55;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

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

В этой статье используется локальная база данных, которая не требует проверки подлинности пользователя. Рабочие приложения должны использовать самый безопасный поток проверки подлинности. Дополнительные сведения о проверке подлинности для развернутых тестовых и рабочих приложений см. в разделе "Безопасные потоки проверки подлинности".

SQL Server Express LocalDB

LocalDB — это упрощенная версия ядра СУБД SQL Server Express, предназначенная для разработки программ. LocalDB запускается по запросу в пользовательском режиме, поэтому настройки не слишком сложны. По умолчанию база данных LocalDB создает файлы *.mdf в каталоге C:\Users\<user>\.

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

    Меню

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

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

    Таблицы Movie, открытые в конструкторе

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

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

    Открытая таблица Movie с отображением данных

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

Создайте класс SeedData в папке Models со следующим кодом:

using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Data;

namespace RazorPagesMovie.Models;

public static class SeedData
{
    public static void Initialize(IServiceProvider serviceProvider)
    {
        using (var context = new RazorPagesMovieContext(
            serviceProvider.GetRequiredService<
                DbContextOptions<RazorPagesMovieContext>>()))
        {
            if (context == null || context.Movie == null)
            {
                throw new ArgumentNullException("Null RazorPagesMovieContext");
            }

            // Look for any movies.
            if (context.Movie.Any())
            {
                return;   // DB has been seeded
            }

            context.Movie.AddRange(
                new Movie
                {
                    Title = "When Harry Met Sally",
                    ReleaseDate = DateTime.Parse("1989-2-12"),
                    Genre = "Romantic Comedy",
                    Price = 7.99M
                },

                new Movie
                {
                    Title = "Ghostbusters ",
                    ReleaseDate = DateTime.Parse("1984-3-13"),
                    Genre = "Comedy",
                    Price = 8.99M
                },

                new Movie
                {
                    Title = "Ghostbusters 2",
                    ReleaseDate = DateTime.Parse("1986-2-23"),
                    Genre = "Comedy",
                    Price = 9.99M
                },

                new Movie
                {
                    Title = "Rio Bravo",
                    ReleaseDate = DateTime.Parse("1959-4-15"),
                    Genre = "Western",
                    Price = 3.99M
                }
            );
            context.SaveChanges();
        }
    }
}

Если в базе данных есть фильмы, возвращается инициализатор заполнения и фильмы не добавляются.

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

Добавление инициализатора заполнения

Обновите следующий выделенный Program.cs код:

using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Data;
using RazorPagesMovie.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));

var app = builder.Build();

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

    SeedData.Initialize(services);
}

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseRouting();

app.UseAuthorization();

app.MapStaticAssets();
app.MapRazorPages();

app.Run();

В предыдущем коде было изменено, Program.cs чтобы выполнить следующие действия:

  • Получение экземпляра контекста базы данных из контейнера внедрения зависимостей (DI).
  • Вызовите метод seedData.Initialize, передав ему экземпляр контекста базы данных.
  • Высвобождение контекста после завершения работы метода заполнения. Оператор using гарантирует удаление контекста.

Если Update-Database не выполнялось, возникает следующее исключение:

SqlException: Cannot open database "RazorPagesMovieContext-" requested by the login. The login failed. Login failed for user 'user name'.

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

Удалите все записи в базе данных для запуска метода seed. Остановите и запустите приложение, чтобы начать заполнение базы данных. Если база данных не заполнена, установите точку останова в if (context.Movie.Any()) и пошагово выполните код.

В приложении отображаются заполненные данные.

Приложение Movie с данными по фильмам, открытое в браузере

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

Объект RazorPagesMovieContext обрабатывает задачу подключения к базе данных и сопоставления объектов Movie с записями базы данных. Контекст базы данных регистрируется с помощью контейнера внедрения зависимостей в файле Program.cs:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RazorPagesMovie.Data;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));

var app = builder.Build();

Система конфигурации ASP.NET Core считывает ключ ConnectionString. Для разработки на локальном уровне конфигурация получает строку подключения из файла appsettings.json.

Созданная строка подключения выглядит аналогично следующему коду JSON.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "RazorPagesMovieContext": "Server=(localdb)\\mssqllocaldb;Database=RazorPagesMovieContext-bc;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

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

В этой статье используется локальная база данных, которая не требует проверки подлинности пользователя. Рабочие приложения должны использовать самый безопасный поток проверки подлинности. Дополнительные сведения о проверке подлинности для развернутых тестовых и рабочих приложений см. в разделе "Безопасные потоки проверки подлинности".

SQL Server Express LocalDB

LocalDB — это упрощенная версия ядра СУБД SQL Server Express, предназначенная для разработки программ. LocalDB запускается по запросу в пользовательском режиме, поэтому настройки не слишком сложны. По умолчанию база данных LocalDB создает файлы *.mdf в каталоге C:\Users\<user>\.

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

    Меню

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

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

    Таблицы Movie, открытые в конструкторе

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

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

    Открытая таблица Movie с отображением данных

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

Создайте класс SeedData в папке Models со следующим кодом:

using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Data;

namespace RazorPagesMovie.Models;

public static class SeedData
{
    public static void Initialize(IServiceProvider serviceProvider)
    {
        using (var context = new RazorPagesMovieContext(
            serviceProvider.GetRequiredService<
                DbContextOptions<RazorPagesMovieContext>>()))
        {
            if (context == null || context.Movie == null)
            {
                throw new ArgumentNullException("Null RazorPagesMovieContext");
            }

            // Look for any movies.
            if (context.Movie.Any())
            {
                return;   // DB has been seeded
            }

            context.Movie.AddRange(
                new Movie
                {
                    Title = "When Harry Met Sally",
                    ReleaseDate = DateTime.Parse("1989-2-12"),
                    Genre = "Romantic Comedy",
                    Price = 7.99M
                },

                new Movie
                {
                    Title = "Ghostbusters ",
                    ReleaseDate = DateTime.Parse("1984-3-13"),
                    Genre = "Comedy",
                    Price = 8.99M
                },

                new Movie
                {
                    Title = "Ghostbusters 2",
                    ReleaseDate = DateTime.Parse("1986-2-23"),
                    Genre = "Comedy",
                    Price = 9.99M
                },

                new Movie
                {
                    Title = "Rio Bravo",
                    ReleaseDate = DateTime.Parse("1959-4-15"),
                    Genre = "Western",
                    Price = 3.99M
                }
            );
            context.SaveChanges();
        }
    }
}

Если в базе данных есть фильмы, возвращается инициализатор заполнения и фильмы не добавляются.

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

Добавление инициализатора заполнения

Обновите следующий выделенный Program.cs код:

using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Data;
using RazorPagesMovie.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));

var app = builder.Build();

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

    SeedData.Initialize(services);
}

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

В предыдущем коде было изменено, Program.cs чтобы выполнить следующие действия:

  • Получение экземпляра контекста базы данных из контейнера внедрения зависимостей (DI).
  • Вызовите метод seedData.Initialize, передав ему экземпляр контекста базы данных.
  • Высвобождение контекста после завершения работы метода заполнения. Оператор using гарантирует удаление контекста.

Если Update-Database не выполнялось, возникает следующее исключение:

SqlException: Cannot open database "RazorPagesMovieContext-" requested by the login. The login failed. Login failed for user 'user name'.

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

Удалите все записи в базе данных для запуска метода seed. Остановите и запустите приложение, чтобы начать заполнение базы данных. Если база данных не заполнена, установите точку останова в if (context.Movie.Any()) и пошагово выполните код.

В приложении отображаются заполненные данные.

Приложение Movie с данными по фильмам, открытое в браузере

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

Объект RazorPagesMovieContext обрабатывает задачу подключения к базе данных и сопоставления объектов Movie с записями базы данных. Контекст базы данных регистрируется с помощью контейнера внедрения зависимостей в файле Program.cs:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RazorPagesMovie.Data;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));

var app = builder.Build();

Система конфигурации ASP.NET Core считывает ключ ConnectionString. Для разработки на локальном уровне конфигурация получает строку подключения из файла appsettings.json.

Созданная строка подключения выглядит аналогично следующему коду JSON.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "RazorPagesMovieContext": "Server=(localdb)\\mssqllocaldb;Database=RazorPagesMovieContext-bc;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

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

В этой статье используется локальная база данных, которая не требует проверки подлинности пользователя. Рабочие приложения должны использовать самый безопасный поток проверки подлинности. Дополнительные сведения о проверке подлинности для развернутых тестовых и рабочих приложений см. в разделе "Безопасные потоки проверки подлинности".

SQL Server Express LocalDB

LocalDB — это упрощенная версия ядра СУБД SQL Server Express, предназначенная для разработки программ. LocalDB запускается по запросу в пользовательском режиме, поэтому настройки не слишком сложны. По умолчанию база данных LocalDB создает файлы *.mdf в каталоге C:\Users\<user>\.

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

    Меню

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

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

    Таблицы Movie, открытые в конструкторе

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

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

    Открытая таблица Movie с отображением данных

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

Создайте класс SeedData в папке Models со следующим кодом:

using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Data;

namespace RazorPagesMovie.Models;

public static class SeedData
{
    public static void Initialize(IServiceProvider serviceProvider)
    {
        using (var context = new RazorPagesMovieContext(
            serviceProvider.GetRequiredService<
                DbContextOptions<RazorPagesMovieContext>>()))
        {
            if (context == null || context.Movie == null)
            {
                throw new ArgumentNullException("Null RazorPagesMovieContext");
            }

            // Look for any movies.
            if (context.Movie.Any())
            {
                return;   // DB has been seeded
            }

            context.Movie.AddRange(
                new Movie
                {
                    Title = "When Harry Met Sally",
                    ReleaseDate = DateTime.Parse("1989-2-12"),
                    Genre = "Romantic Comedy",
                    Price = 7.99M
                },

                new Movie
                {
                    Title = "Ghostbusters ",
                    ReleaseDate = DateTime.Parse("1984-3-13"),
                    Genre = "Comedy",
                    Price = 8.99M
                },

                new Movie
                {
                    Title = "Ghostbusters 2",
                    ReleaseDate = DateTime.Parse("1986-2-23"),
                    Genre = "Comedy",
                    Price = 9.99M
                },

                new Movie
                {
                    Title = "Rio Bravo",
                    ReleaseDate = DateTime.Parse("1959-4-15"),
                    Genre = "Western",
                    Price = 3.99M
                }
            );
            context.SaveChanges();
        }
    }
}

Если в базе данных есть фильмы, возвращается инициализатор заполнения и фильмы не добавляются.

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

Добавление инициализатора заполнения

Обновите следующий выделенный Program.cs код:

using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Data;
using RazorPagesMovie.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));

var app = builder.Build();

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

    SeedData.Initialize(services);
}

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

В предыдущем коде было изменено, Program.cs чтобы выполнить следующие действия:

  • Получение экземпляра контекста базы данных из контейнера внедрения зависимостей (DI).
  • Вызовите метод seedData.Initialize, передав ему экземпляр контекста базы данных.
  • Высвобождение контекста после завершения работы метода заполнения. Оператор using гарантирует удаление контекста.

Если Update-Database не выполнялось, возникает следующее исключение:

SqlException: Cannot open database "RazorPagesMovieContext-" requested by the login. The login failed. Login failed for user 'user name'.

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

Удалите все записи в базе данных для запуска метода seed. Остановите и запустите приложение, чтобы начать заполнение базы данных. Если база данных не заполнена, установите точку останова в if (context.Movie.Any()) и пошагово выполните код.

В приложении отображаются заполненные данные.

Приложение Movie с данными по фильмам, открытое в браузере

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

Объект RazorPagesMovieContext обрабатывает задачу подключения к базе данных и сопоставления объектов Movie с записями базы данных. Контекст базы данных регистрируется с помощью контейнера внедрения зависимостей в файле Program.cs:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RazorPagesMovie.Data;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));

var app = builder.Build();

Система конфигурации ASP.NET Core считывает ключ ConnectionString. Для разработки на локальном уровне конфигурация получает строку подключения из файла appsettings.json.

Созданная строка подключения выглядит аналогично следующему коду JSON.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "RazorPagesMovieContext": "Server=(localdb)\\mssqllocaldb;Database=RazorPagesMovieContext-bc;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

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

В этой статье используется локальная база данных, которая не требует проверки подлинности пользователя. Рабочие приложения должны использовать самый безопасный поток проверки подлинности. Дополнительные сведения о проверке подлинности для развернутых тестовых и рабочих приложений см. в разделе "Безопасные потоки проверки подлинности".

SQL Server Express LocalDB

LocalDB — это упрощенная версия ядра СУБД SQL Server Express, предназначенная для разработки программ. LocalDB запускается по запросу в пользовательском режиме, поэтому настройки не слишком сложны. По умолчанию база данных LocalDB создает файлы *.mdf в каталоге C:\Users\<user>\.

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

    Меню

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

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

    Таблицы Movie, открытые в конструкторе

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

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

    Открытая таблица Movie с отображением данных

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

Создайте класс SeedData в папке Models со следующим кодом:

using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Data;

namespace RazorPagesMovie.Models
{
    public static class SeedData
    {
        public static void Initialize(IServiceProvider serviceProvider)
        {
            using (var context = new RazorPagesMovieContext(
                serviceProvider.GetRequiredService<
                    DbContextOptions<RazorPagesMovieContext>>()))
            {
                if (context == null || context.Movie == null)
                {
                    throw new ArgumentNullException("Null RazorPagesMovieContext");
                }

                // Look for any movies.
                if (context.Movie.Any())
                {
                    return;   // DB has been seeded
                }

                context.Movie.AddRange(
                    new Movie
                    {
                        Title = "When Harry Met Sally",
                        ReleaseDate = DateTime.Parse("1989-2-12"),
                        Genre = "Romantic Comedy",
                        Price = 7.99M
                    },

                    new Movie
                    {
                        Title = "Ghostbusters ",
                        ReleaseDate = DateTime.Parse("1984-3-13"),
                        Genre = "Comedy",
                        Price = 8.99M
                    },

                    new Movie
                    {
                        Title = "Ghostbusters 2",
                        ReleaseDate = DateTime.Parse("1986-2-23"),
                        Genre = "Comedy",
                        Price = 9.99M
                    },

                    new Movie
                    {
                        Title = "Rio Bravo",
                        ReleaseDate = DateTime.Parse("1959-4-15"),
                        Genre = "Western",
                        Price = 3.99M
                    }
                );
                context.SaveChanges();
            }
        }
    }
}

Если в базе данных есть фильмы, возвращается инициализатор заполнения и фильмы не добавляются.

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

Добавление инициализатора заполнения

Обновите следующий выделенный Program.cs код:

using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Data;
using RazorPagesMovie.Models;
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));

var app = builder.Build();

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

    SeedData.Initialize(services);
}

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

В предыдущем коде было изменено, Program.cs чтобы выполнить следующие действия:

  • Получение экземпляра контекста базы данных из контейнера внедрения зависимостей (DI).
  • Вызовите метод seedData.Initialize, передав ему экземпляр контекста базы данных.
  • Высвобождение контекста после завершения работы метода заполнения. Оператор using гарантирует удаление контекста.

Если Update-Database не выполнялось, возникает следующее исключение:

SqlException: Cannot open database "RazorPagesMovieContext-" requested by the login. The login failed. Login failed for user 'user name'.

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

Удалите все записи в базе данных для запуска метода seed. Остановите и запустите приложение, чтобы начать заполнение базы данных. Если база данных не заполнена, установите точку останова в if (context.Movie.Any()) и пошагово выполните код.

В приложении отображаются заполненные данные.

Приложение Movie с данными по фильмам, открытое в браузере

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

Просмотреть или скачать пример кода (описание скачивания).

Объект RazorPagesMovieContext обрабатывает задачу подключения к базе данных и сопоставления объектов Movie с записями базы данных. Контекст базы данных регистрируется с помощью контейнера внедрения зависимостей в методе ConfigureServices в Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();

    services.AddDbContext<RazorPagesMovieContext>(options =>
      options.UseSqlServer(Configuration.GetConnectionString("RazorPagesMovieContext")));
}

Система конфигурации ASP.NET Core считывает ключ ConnectionString. Для разработки на локальном уровне конфигурация получает строку подключения из файла appsettings.json.

Созданная строка подключения выглядит аналогично следующему коду JSON.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "RazorPagesMovieContext": "Server=(localdb)\\mssqllocaldb;Database=RazorPagesMovieContext-bc;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

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

В этой статье используется локальная база данных, которая не требует проверки подлинности пользователя. Рабочие приложения должны использовать самый безопасный поток проверки подлинности. Дополнительные сведения о проверке подлинности для развернутых тестовых и рабочих приложений см. в разделе "Безопасные потоки проверки подлинности".

SQL Server Express LocalDB

LocalDB — это упрощенная версия ядра СУБД SQL Server Express, предназначенная для разработки программ. LocalDB запускается по запросу в пользовательском режиме, поэтому настройки не слишком сложны. По умолчанию база данных LocalDB создает файлы *.mdf в каталоге C:\Users\<user>\.

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

    Меню

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

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

    Таблицы Movie, открытые в конструкторе

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

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

    Открытая таблица Movie с отображением данных

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

Создайте класс SeedData в папке Models со следующим кодом:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RazorPagesMovie.Data;
using System;
using System.Linq;

namespace RazorPagesMovie.Models
{
    public static class SeedData
    {
        public static void Initialize(IServiceProvider serviceProvider)
        {
            using (var context = new RazorPagesMovieContext(
                serviceProvider.GetRequiredService<
                    DbContextOptions<RazorPagesMovieContext>>()))
            {
                // Look for any movies.
                if (context.Movie.Any())
                {
                    return;   // DB has been seeded
                }

                context.Movie.AddRange(
                    new Movie
                    {
                        Title = "When Harry Met Sally",
                        ReleaseDate = DateTime.Parse("1989-2-12"),
                        Genre = "Romantic Comedy",
                        Price = 7.99M
                    },

                    new Movie
                    {
                        Title = "Ghostbusters ",
                        ReleaseDate = DateTime.Parse("1984-3-13"),
                        Genre = "Comedy",
                        Price = 8.99M
                    },

                    new Movie
                    {
                        Title = "Ghostbusters 2",
                        ReleaseDate = DateTime.Parse("1986-2-23"),
                        Genre = "Comedy",
                        Price = 9.99M
                    },

                    new Movie
                    {
                        Title = "Rio Bravo",
                        ReleaseDate = DateTime.Parse("1959-4-15"),
                        Genre = "Western",
                        Price = 3.99M
                    }
                );
                context.SaveChanges();
            }
        }
    }
}

Если в базе данных есть фильмы, возвращается инициализатор заполнения и фильмы не добавляются.

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

Добавление инициализатора заполнения

Замените все содержимое файла Program.cs следующим кодом:

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using RazorPagesMovie.Models;
using System;

namespace RazorPagesMovie
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = CreateHostBuilder(args).Build();

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

                try
                {
                    SeedData.Initialize(services);
                }
                catch (Exception ex)
                {
                    var logger = services.GetRequiredService<ILogger<Program>>();
                    logger.LogError(ex, "An error occurred seeding the DB.");
                }
            }

            host.Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

В приведенном выше коде метод Main изменен, чтобы сделать следующее:

  • Получение экземпляра контекста базы данных из контейнера внедрения зависимостей.
  • Вызовите метод seedData.Initialize, передав ему экземпляр контекста базы данных.
  • Высвобождение контекста после завершения работы метода заполнения. Оператор using гарантирует удаление контекста.

Если Update-Database не выполнялось, возникает следующее исключение:

SqlException: Cannot open database "RazorPagesMovieContext-" requested by the login. The login failed. Login failed for user 'user name'.

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

  1. Удалите все записи в базе данных. Используйте ссылки удаления в браузере или в SSOX.

  2. Необходимо выполнить инициализацию (вызывать методы в классе Startup), чтобы запустить метод заполнения. Для этого следует остановить и перезапустить IIS Express. Закройте и перезапустите службы IIS с помощью любого из перечисленных ниже подходов.

    1. Щелкните правой кнопкой мыши значок IIS Express в области уведомлений и выберите Выйти или Остановить сайт.

      Значок IIS Express в области уведомлений

      Контекстное меню

    2. Если приложение работает в режиме без отладки, нажмите клавишу F5 для запуска в режиме отладки.

    3. Если приложение находится в режиме отладки, остановите отладчик и нажмите клавишу F5.

В приложении отображаются заполненные данные.

Приложение Movie с данными по фильмам, открытое в браузере

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

Просмотреть или скачать пример кода (описание скачивания).

Объект RazorPagesMovieContext обрабатывает задачу подключения к базе данных и сопоставления объектов Movie с записями базы данных. Контекст базы данных регистрируется с помощью контейнера внедрения зависимостей в методе ConfigureServices в Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();

    services.AddDbContext<RazorPagesMovieContext>(options =>
      options.UseSqlServer(Configuration.GetConnectionString("RazorPagesMovieContext")));
}

Система конфигурации ASP.NET Core считывает ключ ConnectionString. Для разработки на локальном уровне конфигурация получает строку подключения из файла appsettings.json.

Созданная строка подключения будет выглядеть следующим образом:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "RazorPagesMovieContext": "Server=(localdb)\\mssqllocaldb;Database=RazorPagesMovieContext-bc;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

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

В этой статье используется локальная база данных, которая не требует проверки подлинности пользователя. Рабочие приложения должны использовать самый безопасный поток проверки подлинности. Дополнительные сведения о проверке подлинности для развернутых тестовых и рабочих приложений см. в разделе "Безопасные потоки проверки подлинности".

SQL Server Express LocalDB

LocalDB — это упрощенная версия ядра СУБД SQL Server Express, предназначенная для разработки программ. LocalDB запускается по запросу в пользовательском режиме, поэтому настройки не слишком сложны. По умолчанию база данных LocalDB создает файлы *.mdf в каталоге C:\Users\<user>\.

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

    Меню

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

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

    Таблицы Movie, открытые в конструкторе

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

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

    Открытая таблица Movie с отображением данных

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

Создайте класс SeedData в папке Models со следующим кодом:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RazorPagesMovie.Data;
using System;
using System.Linq;

namespace RazorPagesMovie.Models
{
    public static class SeedData
    {
        public static void Initialize(IServiceProvider serviceProvider)
        {
            using (var context = new RazorPagesMovieContext(
                serviceProvider.GetRequiredService<
                    DbContextOptions<RazorPagesMovieContext>>()))
            {
                // Look for any movies.
                if (context.Movie.Any())
                {
                    return;   // DB has been seeded
                }

                context.Movie.AddRange(
                    new Movie
                    {
                        Title = "When Harry Met Sally",
                        ReleaseDate = DateTime.Parse("1989-2-12"),
                        Genre = "Romantic Comedy",
                        Price = 7.99M
                    },

                    new Movie
                    {
                        Title = "Ghostbusters ",
                        ReleaseDate = DateTime.Parse("1984-3-13"),
                        Genre = "Comedy",
                        Price = 8.99M
                    },

                    new Movie
                    {
                        Title = "Ghostbusters 2",
                        ReleaseDate = DateTime.Parse("1986-2-23"),
                        Genre = "Comedy",
                        Price = 9.99M
                    },

                    new Movie
                    {
                        Title = "Rio Bravo",
                        ReleaseDate = DateTime.Parse("1959-4-15"),
                        Genre = "Western",
                        Price = 3.99M
                    }
                );
                context.SaveChanges();
            }
        }
    }
}

Если в базе данных есть фильмы, возвращается инициализатор заполнения и фильмы не добавляются.

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

Добавление инициализатора заполнения

Замените все содержимое файла Program.cs следующим кодом:

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using RazorPagesMovie.Models;
using System;

namespace RazorPagesMovie
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = CreateHostBuilder(args).Build();

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

                try
                {
                    SeedData.Initialize(services);
                }
                catch (Exception ex)
                {
                    var logger = services.GetRequiredService<ILogger<Program>>();
                    logger.LogError(ex, "An error occurred seeding the DB.");
                }
            }
            
            host.Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

В приведенном выше коде метод Main изменен, чтобы сделать следующее:

  • Получение экземпляра контекста базы данных из контейнера внедрения зависимостей.
  • Вызовите метод seedData.Initialize, передав ему экземпляр контекста базы данных.
  • Высвобождение контекста после завершения работы метода заполнения. Оператор using гарантирует удаление контекста.

Если Update-Database не выполнялось, возникает следующее исключение:

SqlException: Cannot open database "RazorPagesMovieContext-" requested by the login. The login failed. Login failed for user 'user name'.

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

  • Удалите все записи в базе данных. Используйте ссылки удаления в браузере или в SSOX.

  • Необходимо выполнить инициализацию (вызывать методы в классе Startup), чтобы запустить метод заполнения. Для этого следует остановить и перезапустить IIS Express. Закройте и перезапустите службы IIS с помощью любого из перечисленных ниже подходов.

    • Щелкните правой кнопкой мыши значок IIS Express в области уведомлений и выберите Выйти или Остановить сайт.

      Значок IIS Express в области уведомлений

      Контекстное меню

      • Если приложение работает в режиме без отладки, нажмите клавишу F5 для запуска в режиме отладки.
      • Если приложение находится в режиме отладки, остановите отладчик и нажмите клавишу F5.

В приложении отображаются заполненные данные.

Приложение Movie с данными по фильмам, открытое в Chrome

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