ASP.NET databases met entity framework core in Core

Aanmaakdatum van pagina :

Milieu

Visuele studio
  • Visuele Studio 2019
ASP.NET Kern
  • 3.1 (MVC, De pagina van het scheermes)
SQL-server
  • Express 2019

In het begin

In deze tips ASP.NET stappen voor het gebruik van Entity Framework Core met behulp van de volgende kern aanpak.

Het maken van een database, het gebruik van Entity Framework Core, enzovoort, is niet de belangrijkste focus van deze tips, dus we gaan niet in op details. Ze ASP.NET op dezelfde manier buiten Core gebruikt.

Deze keer wordt sql server geïnstalleerd op een andere server en verbonden door SQL Server authenticatie. Het enige verschil met Windows-verificatie die wordt gebruikt tijdens een lokale installatie is de verbindingsreeks en er is geen verschil in het programma.

Een databasetabel maken

In deze tips wordt SQL Server gebruikt. Installeer SQL Server in uw lokale omgeving of op elke server.

Als u geen database hebt om te testen, maakt u een database.

Als u in SQL maakt, zoals het volgende, wijzigt u het pad naar de SQL Server-versie en de databasenaam die bij uw omgeving passen.

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

Maak een tabel om te testen. Stel de primaire sleutel in voor updates en verwijderingen.

Als u het in SQL wilt maken:

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

Voeg een record toe voor weergave.

Als u het in SQL wilt toevoegen:

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 entiteitskader beschikbaar in Core

Dit item is gemeenschappelijk voor zowel MVC- als Razor-pagina's.

Pakketinstallatie van Entity Framework Core

Zodra u uw project hebt gemaakt, haalt u het pakket op bij NuGet, zodat u eerst Entity Framework Core kunt gebruiken. MVC is een voorbeeld, maar de bewerking is hetzelfde op scheermespagina's.

Klik met de rechtermuisknop op Afhankelijkheden van het project en selecteer NuGet-pakketten beheren.

Als Bladeren is geselecteerd op het tabblad, typt u EntityFrameworkCore in het zoekveld. De Entity Framework Core-gerelateerde pakketten worden in de lijst weergegeven.

Vanaf dit moment zal ik SQL Server gebruiken, dus ik zal de volgende pakketten installeren.

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.Extra
  • Microsoft.EntityFrameworkCore.SqlServer

Laten we Microsoft.EntityFrameworkCore als voorbeeld installeren, dus installeer ook de andere twee.

Selecteer wat u wilt installeren en klik vervolgens op de knop Installeren. De versie selecteert de nieuwste stabilisator.

Het dialoogvenster is in principe ok om op ok te klikken.

Installeer ook de andere twee.

Ik denk dat het pakket als volgt is.

Een model (programma) maken op basis van een databasetabelconfiguratie

Als u gegevens wilt ophalen of bijwerken uit een database in Entity Framework Core, Meestal moet u een programma maken dat een model is op basis van de tabelconfiguratie. Dit model wordt ook wel een aliasentiteit genoemd.

Wanneer u eerst een model, code, een techniek maakt voor het maken van tabellen in een database op basis van een model (programma), of Er is eerst een database, een techniek voor het maken van modellen (programma's) uit tabellen. Hier is een eenvoudige database-eerste manier om automatisch te programmeren vanuit een tabel.

Trouwens, deze stappen zijn ASP.NET naar The Core, zodat je ze op dezelfde manier in de console- of desktop-app kunt maken.

Bouw eerst het project één keer om ervoor te zorgen dat er geen fouten zijn. Als er een fout optreedt, kan het model niet worden gemaakt. U hoeft het niet te bouwen als u al hebt geverifieerd dat er geen fouten zijn.

Open vanuit Visual Studio de Package Manager-console. Anders kunt u het openen vanuit de tools, NuGet Package Manager en Package Manager-consoles in het menu.

U ziet een venster dat vergelijkbaar is met het onderstaande venster, dus zorg ervoor dat het standaardproject rechtsboven het project is dat u wilt modelleren. (Je moet voorzichtig zijn als je meerdere projecten hebt)

Typ in het invoerveld de volgende tekst: De parameters variëren afhankelijk van de omgeving, dus wijzig ze tijdig in de volgende beschrijving. (vooral waar het ***** is in het bijzonder)

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

Een afgebroken -Provider naam, zoals aan de kop van elke naam, is de parameternaam, gevolgd door de waarde van die parameter.

Voorbeeld van
parameterbeschrijvingsparameter
Provider Opgelost in Microsoft.EntityFrameworkCore.SqlServer SQL Server. Microsoft.EntityFrameworkCore.SqlServer
Verbinding Verbindingsreeks voor verbinding met de database. Verbindingsreeksen kunnen gemeenschappelijk in andere apps worden gebruikt, dus schrijf wat u opgeeft volgens de verbindingsreeks kineki. Zowel Windows-verificatie als SQL Server-verificatie zijn beschikbaar. Trouwens, het wordt slechts tijdelijk gebruikt om een model te maken, dus u hoeft zich niet bewust te zijn van de beveiliging nadat de app is gepubliceerd voor deze verbindingsreeks. Pas op voor ontsnappen als je een symbool in je wachtwoord hebt. "Gegevensbron=ServerNaam\SQLEXPRESS;Database=TestDatabase;user id=UserName;password=**********"
F Forceer overschrijven, zelfs als er al een programma is. <Nee >
OutputDir Het mappad waarnaar de code wordt uitgevoerd. Relatief pad uit projectmap Modellen\Database
Context Contextklassenaam bij gebruik van het entiteitskader TestDatabaseDbContext
Databasenamen gebruiken Als dit is opgegeven, wordt de tabelnaam van de database de klassenaam zoals deze is. Anders worden de aanvraag en de meervoudige vorm van de naam van de entiteitsklasse aangepast aan de regels. <Nee >
DataAnnotaties Indien opgegeven, voegt het kolomtype automatisch het kenmerk DataAnnotation toe aan elke eigenschap. Dit is een beetje handig als u de invoer automatisch wilt controleren op basis van het type database. <Nee >

Als u op Enter drukt om het uit te voeren, wordt automatisch code gegenereerd als volgt:

De modelcode voor de tabel Gebruiker is als volgt:

[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; }
}

Overigens wordt de waarschuwing weergegeven omdat de verbindingsreeks wordt weergegeven zoals deze zich in de code van de gegenereerde contextklasse bevindt. Zorg ervoor dat u de methoden in deze contextklasse verwijdert OnConfiguring nadat de code is gegenereerd.

Verbindingsreeksen registreren

Dit ASP.NET kernspecifieke verwerking. (Als u het aanpast, kunt u het gebruiken in andere .NET Core-apps, maar ASP.NET u het standaard voor Core kunt afhandelen.)

De verbindingsreeks die is opgegeven in de Package Manager-console, is alleen gebruikt om het model te genereren.

De verbindings reeks voor het verbinden met de data base als een web-app wordt weer gegeven in appsettings.json. Als u de databasebestemming wilt wijzigen om verbinding mee te maken voor elke build of publicatie, kunt u appsettings gebruiken. Het kan ook worden vertakt door Development.json, enz.

Bovendien, aangezien de verbindingsreeks hier als bewerking wordt gebruikt, laten we maatregelen nemen zoals de verbindingsgebruiker een toegewijde gebruiker maken met het gebied van beveiliging enz.

Als u deze instelt op appsettings.json, maakt u een sectie ConnectionStrings in de hoofd sectie (een object, niet precies een sectie). Maak er een set sleutels en waarden in. De naam van de sleutel kan van alles zijn, maar wordt later gebruikt. De waarde geeft een verbindingsreeks op.

{
  // 

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

Entity Framework Core beschikbaar maken voor programma's

Dit ASP.NET kernspecifieke verwerking. (Als u het aanpast, kunt u het gebruiken in andere .NET Core-apps, maar ASP.NET u het standaard voor Core kunt afhandelen.)

ASP.NET Core heeft elk exemplaar een overlevingstijd, die verschilt van consoles en desktop-apps. Bijvoorbeeld 'Vanaf het moment dat de webservice wordt gestart tot het moment dat deze wordt gestopt' of 'vanaf het moment dat de aanvraag wordt ontvangen tot het antwoord wordt geretourneerd'. ASP.NET framework Core, die in The Core kan worden geplaatst, ServiceLifetime.Scoped geeft standaard aan. Als er geen speciale reden is, kunt u zo blijven.

Als u wilt dat uw programma toegang heeft tot de databasecontext, voegt u deze toe Startup.ConfigureServices aan :

// 追加 (自前のクラスなので名前空間は適時合わせてください)
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> Het typeargument van de methode geeft de contextklasse op die u hebt gemaakt.

options.UseSqlServer De methode geeft aan dat sql server wordt gebruikt.

Configuration.GetConnectionString("TestDatabaseDbContext") hiermee geeft u de sleutel naam op die is geregistreerd bij appsettings.json.

ASP.NET use case in Core MVC

ASP.NET zijn verschillende manieren om Entity Framework Core te gebruiken in Core MVC.

Di (afhankelijkheidsinvoeging) toevoegen aan een controller

Door .cs methode te registreren services.AddDbContext bij het opstarten.cs TestDatabaseDbContext Het kan in de controller worden geplaatst.

Een voorbeeld van DI HomeController is dat de constructeur een argument ILogger<HomeController> logger heeft. Dit wordt toegevoegd door DI. U kunt op TestDatabaseDbContext dezelfde manier invoegen.

Als u HomeController wilt toevoegen aan een bestaande , ziet het er als volgt uit: Natuurlijk kan het worden toegevoegd aan andere controllers.

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;  // 追加
  }
  
  // 省略
}

U hebt vervolgens toegang tot de database met behulp van het exemplaar van de ontvangen context in elke actie.

Gebruikscases

De volgende code is de code die gebruikersvermeldingen en nieuwe registraties verwerkt. Vanaf nu zal ASP.NET core, Entity Framework Core code zijn voor elk, dus ik zal het niet in detail uitleggen.

Het door Framework Core gegenereerde model van de entiteit kan nog steeds worden gebruikt als een model voor acties. U kunt ook een afzonderlijk model maken en het Entity Framework Core-model omwikkelen en gebruiken.

De context wordt ook automatisch verwijderd wanneer de aanvraag van de gebruiker is afgelopen.

HomeController.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));
  }

  // ここまで追加

  // 省略
}

Omdat het lastig is om het scherm handmatig te maken, wordt het lijstscherm automatisch gegenereerd door steigers.

De Views/Home/List.cshtml automatisch gegenereerde is als volgt:

@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 Voeg een koppeling toe aan de schermovergang naar de lijst.

<!-- 省略 -->

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

Het gebruikersregistratiescherm wordt ook automatisch gegenereerd.

De Views/Home/Create.cshtml automatisch gegenereerde is als volgt: Het is moeilijk te gebruiken zoals het is, dus ik heb het een beetje gerepareerd.

@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");}
}

Ren en bevestig. Trouwens, er zijn geen beveiligingsmaatregelen zoals wachtwoordregistratie, dus volg ASP.NET Core- en databaseregistratiemethoden tijdens het werken.

Natuurlijk wordt het weerspiegeld in de database.

Met deze tips worden geen bewerkingen of verwijderingen gemaakt, dus u kunt bewerken aan de rechterkant gebruiken | Details | Delete" veroorzaakt ook een fout. U kunt het op dezelfde manier maken als Maken, dus probeer het eens. De bovenstaande drie processen zijn ook toegevoegd aan de voorbeeldcode.

Databasecontext kregen van RequestServices

Het toevoegen van di aan een controllerconstructor kan een beetje omslachtig zijn omdat je het moet toevoegen aan alle controllers die je nodig hebt. Als alternatief RequestServices kunt u krijgen van .

Het is niet opgenomen in de monstercode, maar het kan als volgt worden verkregen.

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

Direct een databasecontext maken

Het wordt ook gebruikt in consoles en desktop-apps. U kunt deze methode zonder problemen gebruiken. Het wordt niet aanbevolen omdat het bereik van transacties meestal dubbelzinnig is in webtoepassingen waar gelijktijdige toegang waarschijnlijk zal plaatsvinden. Met name updates kunnen mogelijk niet per aanvraag worden teruggedraaid.

Als u de database op deze manier opent, DbContext gebruikt u een techniek om af te leiden .

Wijzig eerst Startup de om mee te Configuration static werken.

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

  // 省略
}

TestDatabaseDbContext Maak een klasse TestDatabaseDbContextEx die is afgeleid van en stel de verbindingsreeks appsettings.json in. Als u een verbindingsreeks kunt instellen, kunt u een andere methode gebruiken, zoals deze doorgeven aan een constructor.

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"));
      }
    }
  }
}

Als u toegang wilt tot de database, genereert en gebruikt u exemplaren van de afgeleide klassen.

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

ASP.NET voorbeeld op een Core Razor-pagina

ASP.NET verschillende manieren om Entity Framework Core te gebruiken op een Core Razor-pagina.

Di (afhankelijkheidsinvoeging) toevoegen aan het paginamodel

Door .cs methode te registreren services.AddDbContext bij het opstarten.cs TestDatabaseDbContext Het kan in een paginamodel worden ingevoegd.

Een voorbeeld van DI IndexModel is dat de constructeur een argument ILogger<IndexModel> logger heeft. Dit wordt toegevoegd door DI. U kunt op TestDatabaseDbContext dezelfde manier invoegen.

Als u IndexModel wilt toevoegen aan een bestaande , ziet het er als volgt uit: Natuurlijk kan het worden toegevoegd aan andere paginamodellen.

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;  // 追加
  }
  
  // 省略
}

Vervolgens kunt u toegang krijgen tot de database met behulp van het exemplaar van de context die u in elk proces hebt ontvangen.

Gebruikscases

De volgende code is de code die gebruikersvermeldingen en nieuwe registraties verwerkt. Zowel ASP.NET Core als Entity Framework Core zal code zijn, dus ik zal niet in details treden. De context wordt ook automatisch verwijderd wanneer de aanvraag van de gebruiker is afgelopen.

Maak een paginamodel voor het lijstscherm.

List.cshtml.cs als volgt:

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 is als volgt gemaakt:

@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>

Voeg het toe aan Index.cshtml, zodat u kunt overschakelen naar de pagina Lijst.

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

Maak ook een gebruikersregistratiescherm.

Create.cshtml.cs code als volgt:

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");
    }
  }
}

Create.cshtml als volgt:

@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>

Ren en bevestig. Trouwens, er zijn geen beveiligingsmaatregelen zoals wachtwoordregistratie, dus volg ASP.NET Core- en databaseregistratiemethoden tijdens het werken.

Natuurlijk wordt het weerspiegeld in de database.

Ik heb geen bewerkingen of verwijderingen gemaakt, dus ik wil niet dat bewerken | Details | Delete" veroorzaakt ook een fout. U kunt het op dezelfde manier maken als Maken, dus probeer het eens. De bovenstaande drie processen zijn ook toegevoegd aan de voorbeeldcode.

Databasecontext kregen van RequestServices

Di toevoegen aan een paginamodelconstructor is een beetje omslachtig omdat je het moet toevoegen aan alle paginamodellen die je nodig hebt. Als alternatief RequestServices kunt u krijgen van .

Het is niet opgenomen in de monstercode, maar het kan als volgt worden verkregen.

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

Direct een databasecontext maken

Het wordt ook gebruikt in consoles en desktop-apps. U kunt deze methode zonder problemen gebruiken. Het wordt niet aanbevolen omdat het bereik van transacties meestal dubbelzinnig is in webtoepassingen waar gelijktijdige toegang waarschijnlijk zal plaatsvinden. Met name updates kunnen mogelijk niet per aanvraag worden teruggedraaid.

Als u de database op deze manier opent, DbContext gebruikt u een techniek om af te leiden .

Wijzig eerst Startup de om mee te Configuration static werken.

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

  // 省略
}

TestDatabaseDbContext Maak een klasse TestDatabaseDbContextEx die is afgeleid van en stel de verbindingsreeks appsettings.json in. Als u een verbindingsreeks kunt instellen, kunt u een andere methode gebruiken, zoals deze doorgeven aan een constructor.

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"));
      }
    }
  }
}

Als u toegang wilt tot de database, genereert en gebruikt u exemplaren van de afgeleide klassen.

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