ASP.NET ฐานข้อมูลโดยใช้กรอบงานเอนทิตีหลักในหลัก

วันที่สร้างเพจ :

สิ่งแวดล้อม

Visual Studio
  • Visual Studio 2019
ASP.NET Core
  • 3.1 (MVC, หน้า Razor)
SQL Server
  • 2019 Express

เริ่มต้นใช้งาน

เคล็ดลับนี้ ASP.NET กระบวนการที่ใช้ แข็งกรอบหลักซึ่งเป็นไปตามเทคโนโลยีหลัก

การสร้างฐานข้อมูล การใช้แกนหลักของกรอบงานเอนทิตี และอื่นๆ ไม่ใช่เนื้อหาหลักของพร้อมท์นี้ ดังนั้นจึงไม่มีคําอธิบายโดยละเอียด พวกเขา ASP.NET ในลักษณะเดียวกันนอกแกน

เวลานี้ผมติดตั้ง SQL Server บนเซิร์ฟเวอร์อื่นและเชื่อมต่อผ่านการรับรองความถูกต้องของ SQL Server ซึ่งแตกต่างจากการรับรองความถูกต้องของ Windows ที่ใช้ในระหว่างการติดตั้งภายในเครื่อง เฉพาะสายอักขระการเชื่อมต่อและโปรแกรมไม่แตกต่างกัน

สร้างตารางฐานข้อมูล

พร้อมท์นี้ใช้ SQL Server คุณติดตั้ง SQL Server ในสภาพแวดล้อมในสถานที่หรือบนเซิร์ฟเวอร์ใด ๆ

ถ้าคุณไม่มีฐานข้อมูลที่จะทดสอบ ให้สร้างฐานข้อมูล

ถ้าคุณต้องการสร้าง SQL โดยใช้ SQL ให้เปลี่ยนเส้นทางรุ่นของ SQL Server และชื่อฐานข้อมูลตามสภาพแวดล้อมของคุณดังนี้:

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

สร้างตารางสําหรับการทดสอบ ตั้งค่าคีย์หลักสําหรับการปรับปรุงหรือการลบ

เมื่อสร้างใน 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

เพิ่มระเบียนเพื่อดู

เมื่อคุณเพิ่มใน 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 หลักใช้กรอบงานเอนทิตี

รายการนี้พบได้ทั่วไปบนหน้า MVC และ Razor

การติดตั้งแพคเกจสําหรับแกนกรอบงานเอนทิตี

หลังจากสร้างโครงการแล้ว ให้รับแพคเกจจาก NuGet ก่อนเพื่อให้คุณสามารถใช้แกนกรอบงานเอนทิตี้ได้ ใช้ MVC เป็นตัวอย่างที่นี่ แต่หน้า Razor ทํางานในลักษณะเดียวกัน

คลิกขวาที่การขึ้นต่อกัน จากโครงการ ของคุณ แล้วเลือก จัดการแพคเกจ NuGet

เลือก เรียกดู จากแท็บ แล้วป้อน EntityFrameworkCore ในฟิลด์การค้นหา รายการแล้วแสดงแพคเกจที่เกี่ยวข้องกับแกนกรอบงานเอนทิตี

เวลานี้เราจะใช้ SQL Server ดังนั้นเราจะติดตั้งแพคเกจต่อไปนี้:

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

เราจะ ใช้ Microsoft.EntityFrameworkCore เป็นตัวอย่างเพื่อติดตั้งดังนั้นโปรดติดตั้งอีกสองอย่างในลักษณะเดียวกัน

เลือกสิ่ง ที่คุณต้องการติดตั้ง แล้วคลิกปุ่ม ติดตั้ง รุ่นเลือกโคลงล่าสุด

โดยทั่วไปไม่มีปัญหากับกล่องโต้ตอบ ให้คลิก ตกลง

กรุณาติดตั้งอีกสอง

ผมคิดว่าแพคเกจที่แสดงด้านล่าง

การสร้างแบบจําลอง (โปรแกรม) จากการตั้งค่าคอนฟิกตารางของฐานข้อมูล

ถ้าคุณต้องการเรียกข้อมูลหรือปรับปรุงข้อมูลจากฐานข้อมูลในแกนกรอบงานเอนทิตี ให้ใช้ คุณต้องเขียนโปรแกรมที่มักจะสร้างแบบจําลองตามการกําหนดค่าตาราง แบบจําลองนี้เรียกอีกอย่างว่าเอนทิตี

เมื่อคุณสร้างแบบจําลอง รหัสแรกเป็นเทคนิคในการสร้างตารางฐานข้อมูลจากแบบจําลอง ( โปรแกรม) ลําดับความสําคัญของฐานข้อมูลเป็นเทคนิคในการสร้างแบบจําลอง ( โปรแกรม) จากตาราง ส่วนนี้อธิบายวิธีการ ตั้งโปรแกรมโดยอัตโนมัติ โดยใช้ตารางลําดับความสําคัญของฐานข้อมูลที่ง่ายต่อการดําเนินการ

โดยวิธีการที่ ASP.NET เหล่านี้เป็นอิสระจากแกนเพื่อให้คุณสามารถสร้างพวกเขาในลักษณะที่คล้ายกันในคอนโซลหรือในการประยุกต์ใช้เดสก์ทอป

ขั้นแรก ให้สร้างโครงการหนึ่งครั้งเพื่อให้แน่ใจว่าไม่มีข้อผิดพลาด ถ้ามีข้อผิดพลาดเกิดขึ้น คุณจะไม่สามารถสร้างแบบจําลองได้ หากคุณได้ตรวจสอบว่าไม่มีข้อผิดพลาดคุณไม่จําเป็นต้องสร้าง

เปิดคอนโซล ตัวจัดการแพคเกจ จาก Visual Studio หากไม่เป็นอยู่ ให้เปิดเครื่องมือ NuGet Pack Manager และคอนโซลตัวจัดการแพคเก็ตจากเมนู

หน้าต่างจะปรากฏขึ้นดังที่แสดงด้านล่างเพื่อให้แน่ใจว่าโครงการเริ่มต้นที่มุมขวาบนเป็นโครงการที่คุณต้องการสร้างแบบจําลอง (คุณจะต้องระมัดระวังถ้าคุณมีหลายรายการ)

ป้อนข้อความต่อไปนี้ลงในช่องป้อนข้อมูล พารามิเตอร์จะแตกต่างกันไปตามสภาพแวดล้อม ดังนั้นให้เปลี่ยนพารามิเตอร์ให้ทันเวลาตามคําแนะนําด้านล่าง (โดยเฉพาะบริเวณ ******)

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

ส่วนหัวของแต่ละ -Provider ชื่อมียัติภังค์ เช่น ชื่อพารามิเตอร์ ตามด้วยค่าพารามิเตอร์

พารามิเตอร์
คําอธิบายพารามิเตอร์ตัวอย่าง
Provider ได้รับการแก้ไขใน Microsoft.EntityFrameworkCore.SqlServer SQL Server Microsoft.EntityFrameworkCore.SqlServer
Connection สตริงการเชื่อมต่อที่ใช้ในการเชื่อมต่อกับฐานข้อมูล เนื่องจากสตริงการเชื่อมต่อยังพบได้ทั่วไปในแอปอื่นๆ ให้อธิบายสิ่งที่คุณต้องการระบุตามสัพติศมาของสตริงการเชื่อมต่อ สามารถใช้สําหรับการรับรองความถูกต้องของ Windows และ SQL Server โดยวิธีการที่จะใช้สําหรับการสร้างแบบจําลองเท่านั้นดังนั้นคุณจึงไม่ต้องกังวลเกี่ยวกับความปลอดภัยของสตริงการเชื่อมต่อนี้หลังจากการเปิดตัวแอป ถ้ารหัสผ่านของคุณมีสัญลักษณ์ ให้ระวังการ escaรหัส "Data Source=ServerName\SQLEXPRESS;Database=TestDatabase;user id=UserName;password=**********"
f บังคับให้เขียนทับโปรแกรมแม้ว่าโปรแกรมจะมีอยู่แล้ว <ไม่มี>
OutputDir เส้นทางโฟลเดอร์ที่จะพิมพ์รหัส เส้นทางที่สัมพันธ์กับโฟลเดอร์โครงการ Models\Database
Context ชื่อคลาสบริบทเมื่อใช้กรอบงานเอนทิตี้ TestDatabaseDbContext
UseDatabaseNames ถ้าระบุ ชื่อตารางของฐานข้อมูลจะกลายเป็นชื่อคลาสตามที่เป็นอยู่ ถ้าไม่ได้ระบุ ตัวพิมพ์ใหญ่และพหูพจน์ของชื่อคลาสเอนทิตีจะถูกปรับตามกฎ <ไม่มี>
DataAnnotations ถ้าระบุ ชนิดคอลัมน์จะแนบคุณสมบัติ DataAnnotation กับแต่ละคุณสมบัติโดยอัตโนมัติ วิธีนี้สะดวกหากคุณต้องการทําการตรวจสอบอินพุตโดยอัตโนมัติตามชนิดของฐานข้อมูล <ไม่มี>

เมื่อคุณกด Enter เรียกใช้ รหัสจะถูกสร้างขึ้นโดยอัตโนมัติเป็นดังนี้:

รหัสแบบจําลองสําหรับตารางผู้ใช้เป็นดังนี้:

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

โดยวิธีการที่คําเตือนเป็นเพราะมันแสดงรายการสตริงการเชื่อมต่อตามที่เป็นอยู่ในรหัสชั้นบริบทที่สร้างขึ้น ตรวจสอบให้แน่ใจว่า OnConfiguring คุณลบวิธีการของคลาสบริบทนี้หลังจากที่คุณสร้างรหัส

ลงทะเบียนสตริงการเชื่อมต่อ

นี่คือ ASP.NET เฉพาะสําหรับ Core (คุณสามารถกําหนดเองได้สําหรับแอป .NET Core อื่นๆ ASP.NET และตามค่าเริ่มต้น จะพร้อมใช้งานสําหรับแกนหลัก)

สตริงการเชื่อมต่อที่ระบุในคอนโซลตัวจัดการแพคเกจจะใช้เพื่อสร้างแบบจําลองเท่านั้น

สตริงการเชื่อมต่อที่เชื่อมต่อกับฐานข้อมูลเป็นเว็บแอปมีให้ใน appsettings.json ถ้าคุณต้องการเปลี่ยนเป้าหมายฐานข้อมูลที่คุณเชื่อมต่อทุกครั้งที่คุณสร้างหรือประกาศ ให้ใช้appsettings นอกจากนี้คุณยังสามารถสาขาโดยใช้ Development.jsonฯลฯ

นอกจากนี้ เนื่องจากสตริงการเชื่อมต่อนี้ถูกใช้เป็นการดําเนินการ ให้ดําเนินการต่างๆ เช่น การเชื่อมต่อผู้ใช้เฉพาะผู้ใช้ โดยคํานึงถึงความปลอดภัย และอื่นๆ

ถ้าตั้งค่าเป็น appsettings.json ให้สร้างส่วน ConnectionStrings ในส่วนราก (เรียกว่าวัตถุอย่างแม่นยํา ไม่ใช่ส่วน) สร้างชุดของคีย์และค่า ชื่อของคีย์ไม่สําคัญ แต่จะใช้ในภายหลัง ค่าเป็นสตริงการเชื่อมต่อ

{
  // 

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

ทําให้กรอบงานเอนทิตี Core พร้อมใช้งานสําหรับโปรแกรม

นี่คือ ASP.NET เฉพาะสําหรับ Core (คุณสามารถกําหนดเองได้สําหรับแอป .NET Core อื่นๆ ASP.NET และตามค่าเริ่มต้น จะพร้อมใช้งานสําหรับแกนหลัก)

ASP.NET หลักซึ่งแตกต่างจากคอนโซลและแอปพลิเคชันเดสก์ท็อปแต่ละอินสแตนซ์มีอายุการใช้งาน ตัวอย่างเช่น "เริ่มต้นจากบริการเว็บเพื่อหยุด" หรือ "จากการรับการร้องขอเพื่อส่งกลับการตอบสนอง" ASP.NET หลักกรอบงานเอนทิตีสามารถวางใน ServiceLifetime.Scoped หลักโดยค่าเริ่มต้น หากมีเหตุผลพิเศษคุณสามารถอยู่ตามที่เป็นอยู่ได้

เมื่อต้องการอนุญาตให้โปรแกรมเข้าถึงบริบทของฐานข้อมูล ให้เพิ่ม Startup.ConfigureServices ลงใน ดังนี้

// 追加 (自前のクラスなので名前空間は適時合わせてください)
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> พารามิเตอร์ชนิดของเมธอดระบุคลาสบริบทที่สร้างขึ้น

options.UseSqlServer วิธีการบ่งชี้การใช้ SQL Server

Configuration.GetConnectionString("TestDatabaseDbContext") ระบุชื่อคีย์ที่ลงทะเบียนใน appsettings.json

ASP.NET ตัวอย่างใน Core MVC

ASP.NET มีหลายวิธีในการใช้กรอบงานเอนทิตี Core กับ Core MVC

ใช้ DI (การแทรกการขึ้นต่อกัน) เพื่อเพิ่มไปยังตัวควบคุม

ลงทะเบียน.cs services.AddDbContext โดยใช้เม TestDatabaseDbContext ธอด Startup สามารถเสียบเข้ากับตัวควบคุมได้

ตัวอย่างของ DI HomeController คือคอนสตรัคเตอร์ ILogger<HomeController> logger เป็นอาร์กิวเมนต์ นี่คือสิ่งที่ DI เพิ่ม นอกจากนี้คุณยัง TestDatabaseDbContext สามารถแทรกในลักษณะเดียวกัน

ถ้าคุณต้องการ HomeController เพิ่มที่มีอยู่ลงใน: แน่นอนคุณสามารถเพิ่มไปยังตัวควบคุมอื่น ๆ

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

จากนั้นคุณเข้าถึงฐานข้อมูลโดยใช้อินสแตนซ์ของบริบทที่ได้รับในแต่ละการดําเนินการ

ใช้ตัวอย่าง

รหัสต่อไปนี้ประมวลผลรายชื่อผู้ใช้และการลงทะเบียนใหม่ ก่อนหน้านี้ ASP.NET รหัสใน Core, แข็งกรอบหลักจึงละเว้นคําอธิบายรายละเอียด

แบบจําลองที่สร้างโดยแกนกรอบงานเอนทิตีสามารถใช้เป็นแบบจําลองสําหรับการดําเนินงานได้ คุณสามารถสร้างแบบจําลองแยกต่างหาก และ wraps แบบจําลองหลักของกรอบงานเอนทิตี้

นอกจากนี้ บริบทจะถูกทําลายโดยอัตโนมัติเมื่อการร้องขอของผู้ใช้สิ้นสุดลง

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

  // ここまで追加

  // 省略
}

เนื่องจากการสร้างหน้าจอด้วยตนเองเป็นเรื่องยุ่งยากจึงสร้างหน้าจอรายการโดยอัตโนมัติโดยใช้ชั้นวางฐาน

การสร้าง Views/Home/List.cshtml อัตโนมัติมีลักษณะดังนี้:

@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 เพิ่มลิงก์การแปลงหน้าจอลงในรายการ

<!-- 省略 -->

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

หน้าจอการลงทะเบียนผู้ใช้จะถูกสร้างขึ้นโดยอัตโนมัติ

การสร้าง Views/Home/Create.cshtml อัตโนมัติมีลักษณะดังนี้: เพราะมันเป็น, มันเป็นเรื่องยากที่จะใช้, ดังนั้นจึงได้รับการแก้ไขเล็กน้อย.

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

เรียกใช้และตรวจสอบ โดยวิธีการที่เนื่องจากไม่มีมาตรการรักษาความปลอดภัยเช่นการลงทะเบียนรหัสผ่านเมื่อดําเนินการโปรดปฏิบัติตาม ASP.NET และเทคนิคการลงทะเบียนฐานข้อมูล

แน่นอนมันสะท้อนให้เห็นในฐานข้อมูล

เนื่องจากพร้อมท์นี้ไม่สร้างกระบวนการแก้ไขหรือ|ลบ Details | ถ้าคุณคลิกลบข้อผิดพลาดเกิดขึ้น คุณสามารถสร้างได้เช่นเดียวกับที่คุณทําดังนั้นลอง โค้ดตัวอย่างยังมีสามขั้นตอนข้างต้น

รับบริบทฐานข้อมูลจาก RequestServices

นี้เป็นบิตยุ่งยากเมื่อเพิ่มคอนสตรัคเตอร์ควบคุมใน DI เพราะตัวควบคุมที่จําเป็นทั้งหมดจะต้องเพิ่ม อีกวิธี RequestServices หนึ่งคือการได้รับมันจาก

ไม่รวมอยู่ในโค้ดตัวอย่าง แต่สามารถรับได้ดังนี้:

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

สร้างบริบทฐานข้อมูลโดยตรง

เทคโนโลยีนี้ยังใช้ในคอนโซลและแอปพลิเคชันเดสก์ท็อป นี้สามารถนํามาใช้โดยไม่มีปัญหาใด ๆ ไม่แนะนําเนื่องจากขอบเขตธุรกรรมสามารถเบลอได้ง่ายในโปรแกรมประยุกต์บนเว็บที่มีการเข้าถึงพร้อมกันจํานวนมาก โดยเฉพาะอย่างยิ่ง ระบบการปรับปรุงอาจไม่สามารถย้อนกลับไปยังหน่วยการร้องขอ

เทคนิคที่ได้รับจะถูก DbContext ใช้เมื่อเข้าถึงฐานข้อมูลในลักษณะนี้

ขั้น Startup 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 สร้างคลาส TestDatabaseDbContextEx ที่ได้รับ และตั้งค่าสายอักขระการเชื่อมต่อสําหรับ appsettings.json ถ้าคุณสามารถตั้งค่าสตริงการเชื่อมต่อ ได้ คุณสามารถดําเนินการอื่นๆ เช่น การส่งผ่านสตริงการเชื่อมต่อผ่านคอนสตรัคเตอร์

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

ถ้าคุณต้องการเข้าถึงฐานข้อมูล ให้สร้างและใช้อินสแตนซ์ของคลาสที่ได้รับ

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

ASP.NET ตัวอย่างบนหน้า Core Razor

ASP.NET มีหลายวิธีในการใช้กรอบทางกายภาพ Core บนหน้า Core Razor

ใช้ DI (การแทรกการขึ้นต่อกัน) เพื่อเพิ่มลงในแบบจําลองเพจ

ลงทะเบียน.cs services.AddDbContext โดยใช้เม TestDatabaseDbContext ธอด Startup สามารถแทรกลงในแบบจําลองเพจได้

ตัวอย่างของ DI IndexModel คือคอนสตรัคเตอร์ ILogger<IndexModel> logger เป็นอาร์กิวเมนต์ นี่คือสิ่งที่ DI เพิ่ม นอกจากนี้คุณยัง TestDatabaseDbContext สามารถแทรกในลักษณะเดียวกัน

ถ้าคุณต้องการ IndexModel เพิ่มที่มีอยู่ลงใน: แน่นอนมันยังสามารถเพิ่มไปยังรูปแบบหน้าอื่น ๆ

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

จากนั้นคุณเข้าถึงฐานข้อมูลโดยใช้อินสแตนซ์ของบริบทที่ได้รับในแต่ละการดําเนินการ

ใช้ตัวอย่าง

รหัสต่อไปนี้ประมวลผลรายชื่อผู้ใช้และการลงทะเบียนใหม่ สอง ASP.NET รหัสใน Core และเอนทิตีกรอบหลัก ดังนั้นคําอธิบายโดยละเอียดจะถูกละเว้น นอกจากนี้ บริบทจะถูกทําลายโดยอัตโนมัติเมื่อการร้องขอของผู้ใช้สิ้นสุดลง

สร้างแบบจําลองหน้าสําหรับหน้าจอรายการ

ตั้งค่า List.cshtml .cs ดังนี้:

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 เป็น ดังนี้:

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

เพิ่ม ใน Index.cshtml เพื่อให้ คุณสามารถไปที่หน้ารายการ

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

สร้างหน้าจอการลงทะเบียนผู้ใช้

ใน Create.cshtml .cs รหัสเป็นดังนี้:

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 เป็น ดังนี้:

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

เรียกใช้และตรวจสอบ โดยวิธีการที่เนื่องจากไม่มีมาตรการรักษาความปลอดภัยเช่นการลงทะเบียนรหัสผ่านเมื่อดําเนินการโปรดปฏิบัติตาม ASP.NET และเทคนิคการลงทะเบียนฐานข้อมูล

แน่นอนมันสะท้อนให้เห็นในฐานข้อมูล

เนื่องจากคุณยังไม่ได้สร้างกระบวนการแก้ไข|หรือลบ Details | ถ้าคุณคลิกลบข้อผิดพลาดเกิดขึ้น คุณสามารถสร้างได้เช่นเดียวกับที่คุณทําดังนั้นลอง โค้ดตัวอย่างยังมีสามขั้นตอนข้างต้น

รับบริบทฐานข้อมูลจาก RequestServices

นี้เป็นบิตยุ่งยากเมื่อเพิ่มคอนสตรัคเตอร์ในรูปแบบหน้าใน DI เพราะทุกรูปแบบหน้าที่จําเป็นจะต้องเพิ่ม อีกวิธี RequestServices หนึ่งคือการได้รับมันจาก

ไม่รวมอยู่ในโค้ดตัวอย่าง แต่สามารถรับได้ดังนี้:

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

สร้างบริบทฐานข้อมูลโดยตรง

เทคโนโลยีนี้ยังใช้ในคอนโซลและแอปพลิเคชันเดสก์ท็อป นี้สามารถนํามาใช้โดยไม่มีปัญหาใด ๆ ไม่แนะนําเนื่องจากขอบเขตธุรกรรมสามารถเบลอได้ง่ายในโปรแกรมประยุกต์บนเว็บที่มีการเข้าถึงพร้อมกันจํานวนมาก โดยเฉพาะอย่างยิ่ง ระบบการปรับปรุงอาจไม่สามารถย้อนกลับไปยังหน่วยการร้องขอ

เทคนิคที่ได้รับจะถูก DbContext ใช้เมื่อเข้าถึงฐานข้อมูลในลักษณะนี้

ขั้น Startup 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 สร้างคลาส TestDatabaseDbContextEx ที่ได้รับ และตั้งค่าสายอักขระการเชื่อมต่อสําหรับ appsettings.json ถ้าคุณสามารถตั้งค่าสตริงการเชื่อมต่อ ได้ คุณสามารถดําเนินการอื่นๆ เช่น การส่งผ่านสตริงการเชื่อมต่อผ่านคอนสตรัคเตอร์

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

ถ้าคุณต้องการเข้าถึงฐานข้อมูล ให้สร้างและใช้อินสแตนซ์ของคลาสที่ได้รับ

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