ASP.NET baz danych przy użyciu programu Entity Framework Core in Core

Data utworzenia strony :

Środowiska

Visual Studio
  • Visual Studio 2019
Rdzeń ASP.NET
  • 3.1 (MVC, strona Razor)
Serwer SQL
  • 2019 Ekspresowe

Na początku

W tym celu ASP.NET kroki do korzystania z entity framework core przy użyciu następujące podejście core.

Tworzenie bazy danych przy użyciu entity framework core i tak dalej nie są głównym celem tej porady, więc nie przejdziemy do szczegółów. Są one ASP.NET używane w ten sam sposób poza Core.

Tym razem serwer SQL jest instalowany na innym serwerze i połączony przez uwierzytelnianie programu SQL Server. Jedyną różnicą od uwierzytelniania systemu Windows używanego podczas instalacji lokalnej jest parametry połączenia i nie ma różnicy w programie.

Tworzenie tabeli bazy danych

Ta porada używa programu SQL Server. Zainstaluj program SQL Server w środowisku lokalnym lub na dowolnym serwerze.

Jeśli nie masz bazy danych do testowania, utwórz bazę danych.

Jeśli tworzysz w języku SQL, takich jak następujące, zmień ścieżkę wersji programu SQL Server i nazwę bazy danych, aby dopasować je do środowiska.

USE [master]
GO

CREATE DATABASE [TestDatabase]
  CONTAINMENT = NONE
  ON  PRIMARY 
( NAME = N'TestDatabase', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL15.SQLEXPRESS\MSSQL\DATA\TestDatabase.mdf' , SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 65536KB )
  LOG ON 
( NAME = N'TestDatabase_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL15.SQLEXPRESS\MSSQL\DATA\TestDatabase_log.ldf' , SIZE = 8192KB , MAXSIZE = 2048GB , FILEGROWTH = 65536KB )
  WITH CATALOG_COLLATION = DATABASE_DEFAULT
GO

Utwórz tabelę do testowania. Ustaw klucz podstawowy dla aktualizacji i usunięć.

Jeśli chcesz go utworzyć w języku SQL:

USE [TestDatabase]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[User](
  [ID] [int] NOT NULL,
  [Name] [nvarchar](20) NOT NULL,
  [Password] [nvarchar](20) NOT NULL,
  [Age] [int] NULL,
  [Email] [nvarchar](200) NULL,
  [Birthday] [date] NULL,
  [UpdateDateTime] [datetime2](7) NULL,
  CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED 
(
  [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

Dodaj rekord do wyświetlenia.

Jeśli chcesz dodać go w języku SQL:

USE [TestDatabase]
GO
INSERT [dbo].[User] ([ID], [Name], [Password], [Age], [Email], [Birthday], [UpdateDateTime]) VALUES (1, N'氏名1', N'aaaa', 20, N'aaaa@example.com', CAST(N'2020-04-01' AS Date), CAST(N'2021-03-14T00:00:00.0000000' AS DateTime2))
GO
INSERT [dbo].[User] ([ID], [Name], [Password], [Age], [Email], [Birthday], [UpdateDateTime]) VALUES (2, N'氏名2', N'bbbb', 30, N'bbbb@example.com', CAST(N'2010-04-01' AS Date), CAST(N'2021-03-14T00:00:00.0000000' AS DateTime2))
GO

ASP.NET struktura jednostek dostępna w

Ten element jest wspólny dla stron MVC i Razor.

Instalacja pakietowa entity framework core

Po utworzeniu projektu pobierz pakiet z NuGet, dzięki czemu można najpierw użyć entity framework core. MVC jest przykładem, ale operacja jest taka sama na stronach maszynki do golenia.

Kliknij prawym przyciskiem myszy zależności z projektu i wybierz pozycję Zarządzaj pakietami NuGet.

Po wybraniu opcji Przeglądaj z karty wpisz w polu wyszukiwania polecenie EntityFrameworkCore. Pakiety związane z rdzeniem entity framework pojawiają się na liście.

Od tego czasu będę używał programu SQL Server, więc zainstaluję następujące pakiety.

  • Microsoft.EntityFrameCore
  • Narzędzie Microsoft.EntityFrameCore.Tools
  • Serwer Microsoft.EntityFrameCore.SqlServer

Zainstalujmy Microsoft.EntityFrameworkCore jako przykład, więc zainstalować pozostałe dwa, jak również.

Wybierz, co chcesz zainstalować, a następnie kliknij przycisk instalacji. Wersja wybiera najnowszy stabilizator.

Okno dialogowe jest w zasadzie ok, aby kliknąć ok.

Zainstaluj również pozostałe dwa.

Myślę, że pakiet jest następujący.

Tworzenie modelu (programu) z konfiguracji tabeli bazy danych

Jeśli chcesz pobrać lub zaktualizować dane z bazy danych w entity framework core, Zwykle należy utworzyć program, który jest modelem opartym na konfiguracji tabeli. Ten model jest również nazywany jednostką aliasu.

Podczas tworzenia modelu, najpierw kod, technika tworzenia tabel w bazie danych z modelu (programu) lub Najpierw istnieje baza danych, która jest techniką tworzenia modeli (programów) z tabel. Oto prosty sposób na automatyczne programować z tabeli.

Nawiasem mówiąc, te kroki są ASP.NET do rdzenia, dzięki czemu można je utworzyć w konsoli lub aplikacji klasycznej w ten sam sposób.

Najpierw najpierw skompiluj projekt raz, aby upewnić się, że nie ma żadnych błędów. Jeśli występuje błąd, nie można utworzyć modelu. Nie musisz go szesnają, jeśli już zweryfikowałeś, że nie ma żadnych błędów.

W programie Visual Studio otwórz konsolę Menedżera pakietów. W przeciwnym razie można go otworzyć z narzędzi, NuGet Package Manager i Menedżer pakietów konsole w menu.

Zobaczysz okno podobne do poniższego, więc upewnij się, że domyślny projekt w prawym górnym rogu jest projekt, który chcesz modelować. (Musisz być ostrożny, jeśli masz wiele projektów)

W polu wejściowym wpisz następujący tekst: Parametry różnią się w zależności od środowiska, więc zmień je w odpowiednim czasie na poniższy opis. (zwłaszcza tam, gdzie jest to ***** w szczególności)

Scaffold-DbContext -Provider Microsoft.EntityFrameworkCore.SqlServer -Connection "Data Source=********\SQLEXPRESS;Database=TestDatabase;user id=********;password=**********" -f -OutputDir "Models\Database" -Context "TestDatabaseDbContext" -UseDatabaseNames -DataAnnotations

Łącznik, -Provider na przykład na czele każdej nazwy, jest nazwą parametru, po której następuje wartość tego parametru.

Przykład parametru opisu parametru
Dostawca Naprawiono w Microsoft.EntityFrameworkCore.SqlServer programie SQL Server. Serwer Microsoft.EntityFrameCore.SqlServer
Połączenia Parametry połączenia do łączenia się z bazą danych. Parametry połączenia mogą być używane w innych aplikacjach wspólnych, więc proszę napisać to, co określisz zgodnie z kineki ciągu połączenia. Dostępne są zarówno uwierzytelnianie systemu Windows, jak i uwierzytelnianie programu SQL Server. Nawiasem mówiąc, jest tylko tymczasowo używany do tworzenia modelu, więc nie trzeba być świadomym zabezpieczeń po opublikowaniu aplikacji dla tego ciągu połączenia. Uważaj na ucieczkę, jeśli masz symbol w haśle. "Źródło danych=Nazwa_serwera\SQLEXPRESS;Baza danych=TestDatabase;identyfikator użytkownika=Nazwa użytkownika;hasło=**********"
F Wymuś nadpisywanie, nawet jeśli istnieje już program. <Nie >
WynikiDir Ścieżka folderu, do której jest wyprowadzany kod. Ścieżka względna z folderu projektu Modele\Baza danych
Kontekście Nazwa klasy kontekstu podczas korzystania z struktury encji TestDatabaseDbContext
Użyj Nazwy bazy danych Jeśli zostanie określona, nazwa tabeli bazy danych staje się nazwą klasy, jak jest. W przeciwnym razie wielkość liter i formularz wielokrotny nazwy klasy jednostki są korygowane zgodnie z regułami. <Nie >
Adnotacje danych Jeśli zostanie określony, typ kolumny automatycznie dołącza atrybut DataAnnotation do każdej właściwości. Jest to nieco przydatne, jeśli chcesz automatycznie sprawdzić dane wejściowe zgodnie z typem bazy danych. <Nie >

Naciśnięcie klawisza Enter w celu jego uruchomienia spowoduje automatyczne wygenerowanie kodu w następujący sposób:

Kod modelu dla tabeli Użytkownik jest następujący:

[Table("User")]
public partial class User
{
  [Key]
  public int ID { get; set; }
  [Required]
  [StringLength(20)]
  public string Name { get; set; }
  [Required]
  [StringLength(20)]
  public string Password { get; set; }
  public int? Age { get; set; }
  [StringLength(200)]
  public string Email { get; set; }
  [Column(TypeName = "date")]
  public DateTime? Birthday { get; set; }
  public DateTime? UpdateDateTime { get; set; }
}

Nawiasem mówiąc, ostrzeżenie jest wyświetlane, ponieważ parametry połączenia jest wymieniony, jak to jest w kodzie klasy kontekstu generowanego. Pamiętaj, aby usunąć OnConfiguring metody w tej klasie kontekstu po wygenerowaniu kodu.

Rejestrowanie ciągów połączeń

To przetwarzanie ASP.NET specyficzne dla rdzenia. (Jeśli go dostosować, można go używać w innych aplikacjach .NET Core, ale ASP.NET można obsługiwać go domyślnie dla Core.)

Ciąg połączenia określony w konsoli Menedżera pakietów był używany tylko do generowania modelu.

Ciąg połączenia do łączenia się z bazą danych jako aplikacja sieci web jest wymieniony w appsettings.json. Jeśli chcesz zmienić miejsce docelowe bazy danych, z którymi chcesz się połączyć dla każdej kompilacji lub publikacji, możesz użyć aplikacji. Może być również rozgałęziony przez Development.json, itp.

Ponadto, ponieważ ciąg połączenia w tym miejscu jest używany jako operacja, podejmijmy środki, takie jak uczynienie użytkownika połączenia dedykowanym użytkownikiem z uwzględnieniem zabezpieczeń itp.

Jeśli ustawisz go na appsettings.json, utwórz connectionstrings sekcji w sekcji głównej (obiekt, nie dokładnie sekcji). Utwórz w nim zestaw kluczy i wartości. Nazwa klucza może być wszystkim, ale zostanie użyta później. Wartość określa parametry połączenia.

{
  // 

  "ConnectionStrings": {
    "TestDatabaseDbContext": "Data Source=ServerName\\SQLEXPRESS;Database=TestDatabase;user id=UserName;password=********"
  }
}

Udostępnianie programów Entity Framework Core

To przetwarzanie ASP.NET specyficzne dla rdzenia. (Jeśli go dostosować, można go używać w innych aplikacjach .NET Core, ale ASP.NET można obsługiwać go domyślnie dla Core.)

ASP.NET Core każde wystąpienie ma czas przetrwania, który różni się od konsol i aplikacji klasycznych. Na przykład "Od momentu rozpoczęcia usługi sieci Web, aż zostanie zatrzymana" lub "od momentu odebraniem żądania do momentu zwrócenia odpowiedzi". ASP.NET framework Core, który może być umieszczony w Core, ServiceLifetime.Scoped określa domyślnie. Jeśli nie ma specjalnego powodu, możesz pozostać w ten sposób.

Aby umożliwić programowi dostęp do kontekstu bazy danych, dodaj Startup.ConfigureServices go do:

// 追加 (自前のクラスなので名前空間は適時合わせてください)
using DatabaseEntityFrameworkCoreMvc.Models.Database;

// 追加
using Microsoft.EntityFrameworkCore;

public class Startup
{
  // 省略

  // このメソッドはランタイムによって呼び出されます。 このメソッドを使用して、コンテナーにサービスを追加します。
  public void ConfigureServices(IServiceCollection services)
  {
    // 省略

    // 追加
    services.AddDbContext<TestDatabaseDbContext>(
      options => options.UseSqlServer(Configuration.GetConnectionString("TestDatabaseDbContext")));
  }

  // 省略

services.AddDbContext<TestDatabaseDbContext> Argument typu metody określa klasę kontekstu, która została utworzona.

options.UseSqlServer Metoda wskazuje, że używany jest serwer SQL.

Configuration.GetConnectionString("TestDatabaseDbContext") określa nazwę klucza zarejestrowaną w pliku appsettings.json.

ASP.NET przypadek użycia w Core MVC

ASP.NET jest kilka sposobów korzystania z entity framework core w core MVC.

Dodawanie di (wstawianie zależności) do kontrolera

Rejestrując metodę .cs services.AddDbContext w starcie.cs TestDatabaseDbContext Można go włożyć do sterownika.

Przykładem DI HomeController jest, że konstruktor ma ILogger<HomeController> logger argument. Jest to dodawane przez DI. Można TestDatabaseDbContext wstawić w ten sam sposób.

Jeśli HomeController chcesz dodać do istniejącego , wygląda to tak: Oczywiście, można go dodać do innych kontrolerów.

using DatabaseEntityFrameworkCoreMvc.Models.Database;  // 追加

// 省略

public class HomeController : Controller
{
  private readonly ILogger<HomeController> _logger;
  
  // 追加
  private readonly TestDatabaseDbContext _dbContext;
  
  public HomeController(ILogger<HomeController> logger, TestDatabaseDbContext dbContext)  // 追加
  {
    _logger = logger;
    _dbContext = dbContext;  // 追加
  }
  
  // 省略
}

Następnie można uzyskać dostęp do bazy danych przy użyciu wystąpienia odebranego kontekstu w każdej akcji.

Przypadki użycia

Poniższy kod to kod, który obsługuje listę użytkowników i nowe rejestracje. Od teraz ASP.NET rdzenia, Entity Framework Core będzie kod dla każdego, więc nie będę szczegółowo wyjaśniać.

Model generowany przez framework framework core nadal może być używany jako model dla akcji. Można również utworzyć oddzielny model i zawinąć i użyć modelu Core entity framework.

Ponadto kontekst jest automatycznie odrzucany po zakończeniu żądania użytkownika.

Strona głównaController.cs

public class HomeController : Controller
{
  private readonly TestDatabaseDbContext _dbContext;

  // 省略

  // ここから追加

  /// <summary>
  /// ユーザー一覧表示アクション。
  /// </summary>
  public IActionResult List()
  {
    // データベースから User 一覧を取得する
    var users = _dbContext.Users.ToList();
    
    // ビューに渡す
    return View(users);
  }
  
  /// <summary>
  /// ユーザー一新規登録画面。
  /// </summary>
  public IActionResult Create()
  {
    return View();
  }
  
  /// <summary>
  /// ユーザー新規登録処理。
  /// </summary>
  [HttpPost]
  public IActionResult Create(User user)
  {
    // エラーがある場合は登録画面に戻る
    if (ModelState.IsValid == false) View(user);
    
    // 更新日時設定
    user.UpdateDateTime = DateTime.Now;

    // 登録リストにユーザー追加
    _dbContext.Users.Add(user);

    // 登録を確定する
    _dbContext.SaveChanges();
    
    // 一覧画面に遷移
    return RedirectToAction(nameof(List));
  }

  // ここまで追加

  // 省略
}

Ponieważ ręczne tworzenie ekranu jest kłopotliwe, ekran listy jest generowany automatycznie przez rusztowania.

Views/Home/List.cshtmlGenerowane automatycznie jest następujące:

@model IEnumerable<DatabaseEntityFrameworkCoreMvc.Models.Database.User>

@{
  ViewData["Title"] = "List";
  Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>List</h1>

<p>
  <a asp-action="Create">Create New</a>
</p>
<table class="table">
  <thead>
    <tr>
      <th>
        @Html.DisplayNameFor(model => model.ID)
      </th>
      <th>
        @Html.DisplayNameFor(model => model.Name)
      </th>
      <th>
        @Html.DisplayNameFor(model => model.Password)
      </th>
      <th>
        @Html.DisplayNameFor(model => model.Age)
      </th>
      <th>
        @Html.DisplayNameFor(model => model.Email)
      </th>
      <th>
        @Html.DisplayNameFor(model => model.Birthday)
      </th>
      <th>
        @Html.DisplayNameFor(model => model.UpdateDateTime)
      </th>
      <th></th>
    </tr>
  </thead>
  <tbody>
@foreach (var item in Model) {
    <tr>
      <td>
        @Html.DisplayFor(modelItem => item.ID)
      </td>
      <td>
        @Html.DisplayFor(modelItem => item.Name)
      </td>
      <td>
        @Html.DisplayFor(modelItem => item.Password)
      </td>
      <td>
        @Html.DisplayFor(modelItem => item.Age)
      </td>
      <td>
        @Html.DisplayFor(modelItem => item.Email)
      </td>
      <td>
        @Html.DisplayFor(modelItem => item.Birthday)
      </td>
      <td>
        @Html.DisplayFor(modelItem => item.UpdateDateTime)
      </td>
      <td>
        @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
        @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
        @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
      </td>
    </tr>
}
  </tbody>
</table>

Index.cshtml Dodaj łącze do przejścia ekranu do listy.

<!-- 省略 -->

<ul>
  <li><a asp-action="List">List</a></li>
</ul>

Automatycznie generowany jest również ekran rejestracji użytkownika.

Views/Home/Create.cshtmlGenerowane automatycznie jest następujące: Jest to trudne w użyciu, jak to jest, więc mam stałe go trochę.

@model DatabaseEntityFrameworkCoreMvc.Models.Database.User

@{
  ViewData["Title"] = "Create";
  Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>Create</h1>

<h4>User</h4>
<hr />
<div class="row">
  <div class="col-md-4">
    <form asp-action="Create">
      <div asp-validation-summary="ModelOnly" class="text-danger"></div>
      <div class="form-group">
        <label asp-for="ID" class="control-label"></label>
        <input asp-for="ID" class="form-control" />
        <span asp-validation-for="ID" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Name" class="control-label"></label>
        <input asp-for="Name" class="form-control" />
        <span asp-validation-for="Name" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Password" class="control-label"></label>
        <input asp-for="Password" class="form-control" type="password" /> <!-- type="password" 追加 -->
        <span asp-validation-for="Password" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Age" class="control-label"></label>
        <input asp-for="Age" class="form-control" />
        <span asp-validation-for="Age" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Email" class="control-label"></label>
        <input asp-for="Email" class="form-control" />
        <span asp-validation-for="Email" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Birthday" class="control-label"></label>
        <input asp-for="Birthday" class="form-control" type="date" /> <!-- type="date" 追加 -->
        <span asp-validation-for="Birthday" class="text-danger"></span>
      </div>
      @* 更新日時は入力しないのでコメントアウト *@
      @*
      <div class="form-group">
        <label asp-for="UpdateDateTime" class="control-label"></label>
        <input asp-for="UpdateDateTime" class="form-control "/>
        <span asp-validation-for="UpdateDateTime" class="text-danger"></span>
      </div>
      *@
      <div class="form-group">
        <input type="submit" value="Create" class="btn btn-primary" />
      </div>
    </form>
  </div>
</div>

<div>
    <a asp-action="List">Back to List</a>  <!-- List に遷移するように変更 -->
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Uruchom i potwierdź. Nawiasem mówiąc, nie ma żadnych środków bezpieczeństwa, takich jak rejestracja hasła, więc należy postępować zgodnie ASP.NET podstawowych i metod rejestracji bazy danych podczas pracy.

Oczywiście jest to odzwierciedlone w bazie danych.

Ta wskazówka nie powoduje tworzenia zmian ani usunień, dzięki czemu można użyć edycji po prawej stronie | Szczegóły | Delete" powoduje również błąd. Można go utworzyć w taki sam sposób jak Tworzenie, więc spróbuj. Powyższe trzy procesy zostały również dodane do przykładowego kodu.

Pobierz kontekst bazy danych z usługi RequestServices

Dodanie di do konstruktora kontrolera może być nieco uciążliwe, ponieważ trzeba dodać go do wszystkich kontrolerów, których potrzebujesz. Alternatywnie, RequestServices można uzyskać z .

Nie jest zawarty w przykładowym kodzie, ale można go uzyskać w następujący sposób.

/// <summary>
/// ユーザー一覧表示アクション。
/// </summary>
public IActionResult List()
{
  // RequestServices からデータベースコンテキストを取得する
  var dbContext = (TestDatabaseDbContext)HttpContext.RequestServices.GetService(typeof(TestDatabaseDbContext));
  
  // データベースから User 一覧を取得する
  var users = dbContext.Users.ToList();
  
  // ビューに渡す
  return View(users);
}

Bezpośrednie tworzenie kontekstu bazy danych

Jest również używany w konsolach i aplikacjach klasycznych. Można użyć tej metody bez żadnych problemów. Nie jest zalecane, ponieważ zakres transakcji wydaje się być niejednoznaczne w aplikacjach sieci Web, gdzie możliwy jest jednoczesny dostęp. W szczególności aktualizacje mogą nie być w stanie zostać wycofane do żądania według żądania.

Jeśli uzyskasz dostęp do bazy danych w ten sposób, DbContext użyjesz techniki, aby wyprowadzić .

Najpierw Startup zmodyfikuj do pracy z Configuration static programem .

public class Startup
{
  public Startup(IConfiguration configuration)
  {
    Configuration = configuration;
    ConfigurationStatic = configuration;  // 追加
  }
  
  public IConfiguration Configuration { get; }
  public static IConfiguration ConfigurationStatic { get; private set; }  // 追加

  // 省略
}

TestDatabaseDbContext Utwórz klasę TestDatabaseDbContextEx pochodną i ustaw parametry połączenia appsettings.json. Jeśli można ustawić ciąg połączenia, można podjąć inną metodę, takich jak przekazywanie go przez konstruktora.

using Microsoft.Extensions.Configuration;
using Microsoft.EntityFrameworkCore;

namespace DatabaseEntityFrameworkCoreMvc.Models.Database
{
  public partial class TestDatabaseDbContextEx : TestDatabaseDbContext
  {
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
      if (!optionsBuilder.IsConfigured)
      {
        optionsBuilder.UseSqlServer(Startup.ConfigurationStatic.GetConnectionString("TestDatabaseDbContext"));
      }
    }
  }
}

Jeśli chcesz uzyskać dostęp do bazy danych, generuj i używaj wystąpień klas pochodnych.

/// <summary>
/// ユーザー一覧表示アクション。
/// </summary>
public IActionResult List()
{
  // 派生クラスのデータベースコンテキストのインスタンスを生成する
  using var dbContext = new TestDatabaseDbContextEx();
  
  // データベースから User 一覧を取得する
  var users = dbContext.Users.ToList();
  
  // ビューに渡す
  return View(users);
}

ASP.NET przykład na stronie Core Razor

ASP.NET na kilka sposobów korzystania z entity framework core na stronie Core Razor.

Dodawanie di (wstawianie zależności) do modelu strony

Rejestrując metodę .cs services.AddDbContext w starcie.cs TestDatabaseDbContext Można go wstawić do modelu strony.

Przykładem DI IndexModel jest, że konstruktor ma ILogger<IndexModel> logger argument. Jest to dodawane przez DI. Można TestDatabaseDbContext wstawić w ten sam sposób.

Jeśli IndexModel chcesz dodać do istniejącego , wygląda to tak: Oczywiście, można go dodać do innych modeli stron.

using DatabaseEntityFrameworkCoreMvc.Models.Database;  // 追加

// 省略

public class IndexModel : PageModel
{
  private readonly ILogger<IndexModel> _logger;
  
  // 追加
  private readonly TestDatabaseDbContext _dbContext;
  
  public IndexModel(ILogger<IndexModel> logger, TestDatabaseDbContext dbContext)  // 追加
  {
    _logger = logger;
    _dbContext = dbContext;  // 追加
  }
  
  // 省略
}

Następnie można uzyskać dostęp do bazy danych przy użyciu wystąpienia kontekstu otrzymanego w każdym procesie.

Przypadki użycia

Poniższy kod to kod, który obsługuje listę użytkowników i nowe rejestracje. Zarówno ASP.NET Core i Entity Framework Core będzie kod, więc nie będę wchodzić w szczegóły. Ponadto kontekst jest automatycznie odrzucany po zakończeniu żądania użytkownika.

Utwórz model strony dla ekranu listy.

Lista.cshtml.cs w następujący sposób:

using System.Collections.Generic;
using System.Linq;
using DatabaseEntityFrameworkCoreRazor.Models.Database;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace DatabaseEntityFrameworkCoreRazor.Pages
{
  public class ListModel : PageModel
  {
    private readonly TestDatabaseDbContext _dbContext;
    
    /// <summary>
    /// 一覧に表示するためのユーザー一覧を格納します。
    /// </summary>
    public List<User> Users { get; set; }
    
    /// <summary>
    /// DI で TestDatabaseDbContext を受け取ります。
    /// </summary>
    /// <param name="dbContext"></param>
    public ListModel(TestDatabaseDbContext dbContext)
    {
      _dbContext = dbContext;
    }
    
    /// <summary>
    /// ページにアクセスされたときに呼ばれます。
    /// </summary>
    public void OnGet()
    {
      // データベースからユーザー一覧を取得します。
      Users = _dbContext.Users.ToList();
    }
  }
}

List.cshtml jest tworzony w następujący sposób:

@page
@model DatabaseEntityFrameworkCoreRazor.Pages.ListModel
@{
}

<h1>List</h1>

<p>
  <a asp-page="Create">Create New</a>
</p>
<table class="table">
  <thead>
    <tr>
      <th>
        @Html.DisplayNameFor(model => model.Users[0].ID)
      </th>
      <th>
        @Html.DisplayNameFor(model => model.Users[0].Name)
      </th>
      <th>
        @Html.DisplayNameFor(model => model.Users[0].Password)
      </th>
      <th>
        @Html.DisplayNameFor(model => model.Users[0].Age)
      </th>
      <th>
        @Html.DisplayNameFor(model => model.Users[0].Email)
      </th>
      <th>
        @Html.DisplayNameFor(model => model.Users[0].Birthday)
      </th>
      <th>
        @Html.DisplayNameFor(model => model.Users[0].UpdateDateTime)
      </th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    @foreach (var item in Model.Users)
    {
      <tr>
        <td>
          @Html.DisplayFor(modelItem => item.ID)
        </td>
        <td>
          @Html.DisplayFor(modelItem => item.Name)
        </td>
        <td>
          @Html.DisplayFor(modelItem => item.Password)
        </td>
        <td>
          @Html.DisplayFor(modelItem => item.Age)
        </td>
        <td>
          @Html.DisplayFor(modelItem => item.Email)
        </td>
        <td>
          @Html.DisplayFor(modelItem => item.Birthday)
        </td>
        <td>
          @Html.DisplayFor(modelItem => item.UpdateDateTime)
        </td>
        <td>
          <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
          <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
          <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
        </td>
      </tr>
    }
  </tbody>
</table>

Dodaj go do pliku Index.cshtml, aby można było przejść do strony Lista.

<!-- 追加 -->
<ul>
  <li><a asp-page="List">List</a></li>
</ul>

Utwórz również ekran rejestracji użytkownika.

Utwórz.cshtml.cs kod w następujący sposób:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DatabaseEntityFrameworkCoreRazor.Models.Database;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace DatabaseEntityFrameworkCoreRazor.Pages
{
  public class CreateModel : PageModel
  {
    private readonly TestDatabaseDbContext _dbContext;

    /// <summary>
    /// 登録するユーザー情報を格納します。
    /// </summary>
    [BindProperty]
    public User UserInfo { get; set; }

    /// <summary>
    /// DI で TestDatabaseDbContext を受け取ります。
    /// </summary>
    /// <param name="dbContext"></param>
    public CreateModel(TestDatabaseDbContext dbContext)
    {
      _dbContext = dbContext;
    }

    /// <summary>
    /// ページにアクセスされたときに呼ばれます。
    /// </summary>
    public void OnGet()
    {
      // 画面表示時は何もしません。
    }

    /// <summary>
    /// POST が送信されたときに呼ばれる。
    /// </summary>
    public IActionResult OnPost()
    {
      // エラーがある場合は登録画面に戻る
      if (ModelState.IsValid == false) return Page();

      // 更新日時設定
      UserInfo.UpdateDateTime = DateTime.Now;

      // 登録リストにユーザー追加
      _dbContext.Users.Add(UserInfo);

      // 登録を確定する
      _dbContext.SaveChanges();

      // 一覧画面に遷移
      return RedirectToPage("List");
    }
  }
}

Utwórz plik cshtml w następujący sposób:

@page
@model DatabaseEntityFrameworkCoreRazor.Pages.CreateModel
@{
}

<h1>Create</h1>

<h4>User</h4>
<hr />
<div class="row">
  <div class="col-md-4">
    <form asp-action="Create">
      <div asp-validation-summary="ModelOnly" class="text-danger"></div>
      <div class="form-group">
        <label asp-for="UserInfo.ID" class="control-label"></label>
        <input asp-for="UserInfo.ID" class="form-control" />
        <span asp-validation-for="UserInfo.ID" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="UserInfo.Name" class="control-label"></label>
        <input asp-for="UserInfo.Name" class="form-control" />
        <span asp-validation-for="UserInfo.Name" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="UserInfo.Password" class="control-label"></label>
        <input asp-for="UserInfo.Password" class="form-control" type="password" />
        <span asp-validation-for="UserInfo.Password" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="UserInfo.Age" class="control-label"></label>
        <input asp-for="UserInfo.Age" class="form-control" />
        <span asp-validation-for="UserInfo.Age" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="UserInfo.Email" class="control-label"></label>
        <input asp-for="UserInfo.Email" class="form-control" />
        <span asp-validation-for="UserInfo.Email" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="UserInfo.Birthday" class="control-label"></label>
        <input asp-for="UserInfo.Birthday" class="form-control" type="date" />
        <span asp-validation-for="UserInfo.Birthday" class="text-danger"></span>
      </div>
      @*
        <div class="form-group">
          <label asp-for="UpdateDateTime" class="control-label"></label>
          <input asp-for="UpdateDateTime" class="form-control" />
          <span asp-validation-for="UpdateDateTime" class="text-danger"></span>
        </div>
      *@
      <div class="form-group">
        <input type="submit" value="Create" class="btn btn-primary" />
      </div>
    </form>
  </div>
</div>

<div>
  <a asp-page="List">Back to List</a>
</div>

Uruchom i potwierdź. Nawiasem mówiąc, nie ma żadnych środków bezpieczeństwa, takich jak rejestracja hasła, więc należy postępować zgodnie ASP.NET podstawowych i metod rejestracji bazy danych podczas pracy.

Oczywiście jest to odzwierciedlone w bazie danych.

Nie utworzyłem żadnych zmian ani usunień, więc nie chcę edytować | Szczegóły | Delete" powoduje również błąd. Można go utworzyć w taki sam sposób jak Tworzenie, więc spróbuj. Powyższe trzy procesy zostały również dodane do przykładowego kodu.

Pobierz kontekst bazy danych z usługi RequestServices

Dodawanie di do konstruktora modelu strony jest nieco kłopotliwe, ponieważ trzeba dodać go do wszystkich modeli stron, których potrzebujesz. Alternatywnie, RequestServices można uzyskać z .

Nie jest zawarty w przykładowym kodzie, ale można go uzyskać w następujący sposób.

/// <summary>
/// ページにアクセスされたときに呼ばれます。
/// </summary>
public void OnGet()
{
  // RequestServices からデータベースコンテキストを取得する
  var dbContext = (TestDatabaseDbContext)HttpContext.RequestServices.GetService(typeof(TestDatabaseDbContext));
  
  // データベースからユーザー一覧を取得します。
  Users = dbContext.Users.ToList();
}

Bezpośrednie tworzenie kontekstu bazy danych

Jest również używany w konsolach i aplikacjach klasycznych. Można użyć tej metody bez żadnych problemów. Nie jest zalecane, ponieważ zakres transakcji wydaje się być niejednoznaczne w aplikacjach sieci Web, gdzie możliwy jest jednoczesny dostęp. W szczególności aktualizacje mogą nie być w stanie zostać wycofane do żądania według żądania.

Jeśli uzyskasz dostęp do bazy danych w ten sposób, DbContext użyjesz techniki, aby wyprowadzić .

Najpierw Startup zmodyfikuj do pracy z Configuration static programem .

public class Startup
{
  public Startup(IConfiguration configuration)
  {
    Configuration = configuration;
    ConfigurationStatic = configuration;  // 追加
  }
  
  public IConfiguration Configuration { get; }
  public static IConfiguration ConfigurationStatic { get; private set; }  // 追加

  // 省略
}

TestDatabaseDbContext Utwórz klasę TestDatabaseDbContextEx pochodną i ustaw parametry połączenia appsettings.json. Jeśli można ustawić ciąg połączenia, można podjąć inną metodę, takich jak przekazywanie go przez konstruktora.

using Microsoft.Extensions.Configuration;
using Microsoft.EntityFrameworkCore;

namespace DatabaseEntityFrameworkCoreRazor.Models.Database
{
  public partial class TestDatabaseDbContextEx : TestDatabaseDbContext
  {
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
      if (!optionsBuilder.IsConfigured)
      {
        optionsBuilder.UseSqlServer(Startup.ConfigurationStatic.GetConnectionString("TestDatabaseDbContext"));
      }
    }
  }
}

Jeśli chcesz uzyskać dostęp do bazy danych, generuj i używaj wystąpień klas pochodnych.

/// <summary>
/// ページにアクセスされたときに呼ばれます。
/// </summary>
public void OnGet()
{
  // 派生クラスのデータベースコンテキストのインスタンスを生成する
  using var dbContext = new TestDatabaseDbContextEx();
    
  // データベースからユーザー一覧を取得します。
  Users = dbContext.Users.ToList();
}