ASP.NET database utilizzando Entity Framework Core in Core

Data di creazione della pagina :

ambiente

Visual Studio
  • Visual Studio 2019
ASP.NET Nucleo
  • 3.1 (MVC, pagina Rasoio)
SQL Server
  • Express 2019

dapprima

In questo ASP.NET procedura per utilizzare Entity Framework Core utilizzando l'approccio di base seguente.

La creazione di un database, l'utilizzo di Entity Framework Core e così via non sono l'obiettivo principale di questi suggerimenti, quindi non andremo nei dettagli. Sono ASP.NET allo stesso modo al di fuori di Core.

Questa volta, sql server viene installato in un server diverso e connesso tramite l'autenticazione di SQL Server. L'unica differenza rispetto all'autenticazione di Windows utilizzata durante un'installazione locale è la stringa di connessione e non c'è differenza nel programma.

Creare una tabella di database

In questo tips viene utilizzato SQL Server. Installare SQL Server nell'ambiente locale o in qualsiasi server.

Se non si dispone di un database per il test, creare un database.

Se si sta creando in SQL, ad esempio il seguente, modificare il percorso della versione e il nome del database di SQL Server in base all'ambiente.

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

Creare una tabella per il test. Impostare la chiave primaria per gli aggiornamenti e le eliminazioni.

Se si desidera crearlo in 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

Aggiungere un record per la visualizzazione.

Se si desidera aggiungerlo in 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 quadro di entità disponibile in Core

Questo elemento è comune sia alle pagine MVC che Razor.

Installazione del pacchetto di Entity Framework Core

Dopo aver creato il progetto, ottenere il pacchetto da NuGet in modo da poter utilizzare prima Entity Framework Core. MVC è un esempio, ma l'operazione è la stessa sulle pagine del rasoio.

Fare clic con il pulsante destro del mouse su Dipendenze dal progetto e scegliere Gestisci pacchetti NuGet.

Con Sfoglia selezionato dalla scheda, digitare EntityFrameworkCore nel campo di ricerca. I pacchetti relativi al core di Entity Framework vengono visualizzati nell'elenco.

Da questo momento, utilizzerò SQL Server, quindi installerò i pacchetti seguenti.

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.Tools
  • Microsoft.EntityFrameworkCore.SqlServer

Installiamo Microsoft.EntityFrameworkCore come esempio, quindi installa anche gli altri due.

Selezionare gli utenti da installare e quindi fare clic sul pulsante installa. La versione seleziona l'ultimo stabilizzatore.

La finestra di dialogo è fondamentalmente ok per fare clic su OK.

Installare anche gli altri due.

Ritengo che il pacchetto sia il seguente.

Creare un modello (programma) da una configurazione di tabella di database

Se si desidera recuperare o aggiornare dati da un database in Entity Framework Core, In genere è necessario creare un programma che sia un modello basato sulla configurazione della tabella. Questo modello è anche chiamato entità alias.

Quando si crea un modello, prima il codice, una tecnica per la creazione di tabelle in un database da un modello (programma) o C'è prima il database, che è una tecnica per la creazione di modelli (programmi) dalle tabelle. Ecco un semplice modo per programmare automaticamente da una tabella.

A proposito, questi passaggi vengono ASP.NET a The Core, in modo da poterli creare nella console o nell'app desktop allo stesso modo.

Innanzitutto, compila il progetto una volta per assicurarti che non ci siano errori. Se si verifica un errore, non è possibile creare il modello. Non è necessario costruirlo se hai già verificato che non ci sono errori.

Da Visual Studio aprire la console di Gestione pacchetti. In caso contrario, è possibile aprirlo dalle console strumenti, NuGet Package Manager e Package Manager del menu.

Verrà visualizzata una finestra simile a quella seguente, quindi assicurarsi che il progetto predefinito in alto a destra sia il progetto che si desidera modellare. (Devi stare attento se hai più progetti)

Nel campo di input digitare il testo seguente: I parametri variano a seconda dell'ambiente, quindi si prega di modificarli in modo tempestivo alla seguente descrizione. (specialmente dove si trova ***** in particolare)

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

Uno -Provider sillabato, ad esempio all'inizio di ogni nome, è il nome del parametro, seguito dal valore di tale parametro.

Esempio di parametro Descrizione parametro
provider Risolto in Microsoft.EntityFrameworkCore.SqlServer SQL Server. Microsoft.EntityFrameworkCore.SqlServer
connessione Stringa di connessione per la connessione al database. Le stringhe di connessione possono essere utilizzate in altre app in comune, quindi scrivi ciò che specifichi in base alla stringa di connessione kineki. Sono disponibili sia l'autenticazione di Windows che l'autenticazione di SQL Server. A proposito, viene utilizzato solo temporaneamente per creare un modello, quindi non è necessario essere consapevoli della sicurezza dopo la pubblicazione dell'app per questa stringa di connessione. Fai attenzione a fuggire se hai un simbolo nella password. "Data Source=NomeServer\SQLEXPRESS;Database=TestDatabase;id utente=NomeUtente;password=***********"
F Forza la sovrascrittura anche se c'è già un programma. <No >
OutputDir Percorso della cartella in cui viene e output il codice. Percorso relativo dalla cartella del progetto Modelli\Database
contesto Nome della classe di contesto quando si utilizza Entity Framework TestDatabaseDbContext
UseDatabaseNames Se specificato, il nome della tabella del database diventa il nome della classe così com'è. In caso contrario, il caso e la forma multipla del nome della classe di entità vengono regolati in base alle regole. <No >
DataAnnotations Se specificato, il tipo di colonna aggiunge automaticamente l'attributo DataAnnotation a ciascuna proprietà. Questo è un po 'utile se si desidera controllare automaticamente l'input in base al tipo di database. <No >

Premendo INVIO per eseguito verrà generato automaticamente il codice come segue:

Il codice del modello per la tabella User è il seguente:

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

A proposito, l'avviso viene visualizzato perché la stringa di connessione è elencata così com'è nel codice della classe di contesto generata. Assicurarsi di eliminare i OnConfiguring metodi in questa classe di contesto dopo la produzione del codice.

Registrare le stringhe di connessione

Questo ASP.NET'elaborazione specifica del core. Se lo personalizzi, puoi usarlo in altre app .NET Core, ma ASP.NET gestirlo per impostazione predefinita per Core.

La stringa di connessione specificata nella console di Gestione pacchetti è stata utilizzata solo per generare il modello.

La stringa di connessione per la connessione al database come app Web è elencata in appsettings.json. Se si desidera modificare la destinazione del database a cui connettersi per ogni compilazione o pubblicazione, è possibile utilizzare le impostazioni dell'app. Può anche essere ramificata da Development.json, ecc.

Inoltre, poiché la stringa di connessione qui viene utilizzata come operazione, prendiamo misure come rendere l'utente di connessione un utente dedicato in considerazione della sicurezza, ecc.

Se lo impostate su appsettings.json, create una sezione ConnectionStrings nella sezione radice (un oggetto, non esattamente una sezione). Creare un set di chiavi e valori. Il nome della chiave può essere qualsiasi cosa, ma verrà utilizzato in seguito. Il valore specifica una stringa di connessione.

{
  // 

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

Rendere Entity Framework Core disponibile per i programmi

Questo ASP.NET'elaborazione specifica del core. Se lo personalizzi, puoi usarlo in altre app .NET Core, ma ASP.NET gestirlo per impostazione predefinita per Core.

ASP.NET Core, ogni istanza ha un tempo di sopravvivenza, che è diverso dalle console e dalle app desktop. Ad esempio, "Dal momento in cui il servizio Web viene avviato fino all'arresto" o "dal momento in cui la richiesta viene ricevuta fino alla restituzione della risposta". ASP.NET framework Core, che può essere inserito in The Core, specifica ServiceLifetime.Scoped per impostazione predefinita. Se non c'è un motivo speciale, puoi rimanere così.

Per consentire al programma di accedere al contesto del database, Startup.ConfigureServices aggiungerlo a :

// 追加 (自前のクラスなので名前空間は適時合わせてください)
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> L'argomento di tipo del metodo specifica la classe di contesto creata.

options.UseSqlServer Il metodo indica che viene utilizzato sql server.

Configuration.GetConnectionString("TestDatabaseDbContext") specifica il nome della chiave registrato con appsettings.json.

ASP.NET caso d'uso in Core MVC

ASP.NET diversi modi per utilizzare Entity Framework Core in Core MVC.

Aggiungere di (inserimento delle dipendenze) a un controller

Registrando il .cs services.AddDbContext di avvio.cs TestDatabaseDbContext Può essere inserito nel controller.

Un esempio di DI HomeController è che il costruttore ha un ILogger<HomeController> logger argomento. Questo viene aggiunto da DI. È possibile inserire TestDatabaseDbContext nello stesso modo.

Se si HomeController desidera aggiungere a un oggetto esistente , è simile al seguente: Naturalmente, può essere aggiunto ad altri controller.

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

È quindi possibile accedere al database utilizzando l'istanza del contesto ricevuto in ogni azione.

Casi d'uso

Il codice seguente è il codice che gestisce l'elenco degli utenti e le nuove registrazioni. D'ora in ASP.NET, Entity Framework Core sarà codice per ciascuno, quindi non spiegherò in dettaglio.

Il modello generato dal core di entity Framework può ancora essere utilizzato come modello per le azioni. È inoltre possibile creare un modello separato e disporre e utilizzare il modello Entity Framework Core.

Inoltre, il contesto viene automaticamente scartato al momento della fine della richiesta dell'utente.

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

  // ここまで追加

  // 省略
}

Poiché è problematico creare lo schermo manualmente, la schermata dell'elenco viene generata automaticamente dalle impalcature.

La Views/Home/List.cshtml generata automaticamente è la seguente:

@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 Aggiungere un collegamento alla transizione dello schermo all'elenco.

<!-- 省略 -->

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

Anche la schermata di registrazione dell'utente viene generata automaticamente.

La Views/Home/Create.cshtml generata automaticamente è la seguente: È difficile da usare così com'è, quindi l'ho risolto un po '.

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

Eseguire e confermare. A proposito, non ci sono misure di sicurezza come la registrazione delle password, quindi segui i metodi ASP.NET di registrazione del core e del database quando si opera.

Naturalmente, si riflette nel database.

Questo suggerimenti non crea modifiche o eliminazioni, pertanto è possibile utilizzare la modifica a destra | Dettagli | Delete" causa anche un errore. Puoi crearlo allo stesso modo di Crea, quindi provalo. I tre processi precedenti sono stati aggiunti anche al codice di esempio.

Ottenere il contesto del database da RequestServices

L'aggiunta di a un costruttore di controller può essere un po 'ingombrante perché è necessario aggiungerlo a tutti i controller necessari. In alternativa, RequestServices è possibile ottenere da .

Non è incluso nel codice di esempio, ma può essere ottenuto come segue.

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

Creare direttamente un contesto di database

Viene utilizzato anche in console e app desktop. È possibile utilizzare questo metodo senza problemi. Non è consigliabile perché l'ambito delle transazioni tende ad essere ambiguo nelle applicazioni Web in cui è probabile che si verifichi l'accesso simultaneo. In particolare, gli aggiornamenti potrebbero non essere in grado di essere ripristinati su base richiesta per richiesta.

Se si accede al database in questo modo, DbContext si utilizzerà una tecnica per derivare .

Modificare innanzitutto Startup l'in modo che funzioni con Configuration static .

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

  // 省略
}

TestDatabaseDbContext Creare una classe TestDatabaseDbContextEx derivata da e impostare la stringa di connessione appsettings.json. Se è possibile impostare una stringa di connessione, è possibile eseguire un altro metodo, ad esempio passandola attraverso un costruttore.

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

Se si desidera accedere al database, generare e utilizzare istanze delle classi derivate.

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

ASP.NET esempio in una pagina Core Razor

ASP.NET diversi modi per utilizzare Entity Framework Core in una pagina Core Razor.

Aggiungere di (inserimento di dipendenza) al modello di pagina

Registrando il .cs services.AddDbContext di avvio.cs TestDatabaseDbContext Può essere inserito in un modello di pagina.

Un esempio di DI IndexModel è che il costruttore ha un ILogger<IndexModel> logger argomento. Questo viene aggiunto da DI. È possibile inserire TestDatabaseDbContext nello stesso modo.

Se si IndexModel desidera aggiungere a un oggetto esistente , è simile al seguente: Naturalmente, può essere aggiunto ad altri modelli di pagina.

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

È quindi possibile accedere al database utilizzando l'istanza del contesto ricevuto in ogni processo.

Casi d'uso

Il codice seguente è il codice che gestisce l'elenco degli utenti e le nuove registrazioni. Sia ASP.NET Core che Entity Framework Core saranno codice, quindi non andrò nei dettagli. Inoltre, il contesto viene automaticamente scartato al momento della fine della richiesta dell'utente.

Creare un modello di pagina per la schermata dell'elenco.

List.cshtml.cs come segue:

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 viene creato come segue:

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

Aggiungerlo a Index.cshtml in modo da poter passare alla pagina Elenco.

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

Crea anche una schermata di registrazione utente.

Create.cshtml.cs codice come segue:

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 come segue:

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

Eseguire e confermare. A proposito, non ci sono misure di sicurezza come la registrazione delle password, quindi segui i metodi ASP.NET di registrazione del core e del database quando si opera.

Naturalmente, si riflette nel database.

Non ho creato modifiche o eliminazioni, quindi non voglio che la modifica | Dettagli | Delete" causa anche un errore. Puoi crearlo allo stesso modo di Crea, quindi provalo. I tre processi precedenti sono stati aggiunti anche al codice di esempio.

Ottenere il contesto del database da RequestServices

L'aggiunta di a un costruttore del modello di pagina è un po 'ingombrante perché è necessario aggiungerlo a tutti i modelli di pagina necessari. In alternativa, RequestServices è possibile ottenere da .

Non è incluso nel codice di esempio, ma può essere ottenuto come segue.

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

Creare direttamente un contesto di database

Viene utilizzato anche in console e app desktop. È possibile utilizzare questo metodo senza problemi. Non è consigliabile perché l'ambito delle transazioni tende ad essere ambiguo nelle applicazioni Web in cui è probabile che si verifichi l'accesso simultaneo. In particolare, gli aggiornamenti potrebbero non essere in grado di essere ripristinati su base richiesta per richiesta.

Se si accede al database in questo modo, DbContext si utilizzerà una tecnica per derivare .

Modificare innanzitutto Startup l'in modo che funzioni con Configuration static .

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

  // 省略
}

TestDatabaseDbContext Creare una classe TestDatabaseDbContextEx derivata da e impostare la stringa di connessione appsettings.json. Se è possibile impostare una stringa di connessione, è possibile eseguire un altro metodo, ad esempio passandola attraverso un costruttore.

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

Se si desidera accedere al database, generare e utilizzare istanze delle classi derivate.

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