เตรียมการเข้าถึง SQL Server โดยใช้ Entity Framework Core (ฐานข้อมูลก่อน)
สภาพแวดล้อมในการทํางาน
- วิชวลสตูดิโอ
-
- วิชวลสตูดิโอ 2022
- ตาข่าย
-
- .NET 8
- แกน Entity Framework
-
- Entity Framework Core 8.0
- เซิร์ฟเวอร์ SQL
-
- SQL Server 2022
* ข้างต้นเป็นสภาพแวดล้อมการตรวจสอบ แต่อาจใช้ได้กับเวอร์ชันอื่น
ทีแรก
Entity Framework Core เป็นไลบรารีของตัวแมป O/R เมื่อเข้าถึงฐานข้อมูล คุณสามารถเข้าถึงระเบียนของฐานข้อมูลผ่านโมเดล (คลาส) ที่กําหนดไว้ในโค้ด โดยไม่ต้องใช้คําสั่ง SQL โดยตรง สิ่งนี้ให้ประโยชน์ดังต่อไปนี้:
- เนื่องจากคําสั่ง SQL ไม่ได้เขียนโดยตรง ความเสี่ยงด้านความปลอดภัย เช่น การแทรก SQL จะลดลง
- เนื่องจากคําสั่ง SQL เป็นสตริง แม้ว่าคุณจะทําผิดพลาดในไวยากรณ์ แต่ก็ไม่ได้รับการตรวจสอบข้อผิดพลาดในการสร้าง แต่เนื่องจากโมเดลเป็นไวยากรณ์ของโปรแกรม คุณจึงสามารถตรวจสอบข้อผิดพลาดได้ในเวลาที่สร้าง
Entity Framework Core สามารถสร้างโค้ดจากฐานข้อมูลที่มีอยู่โดยอัตโนมัติเพื่อเชื่อมต่อกับแบบจําลองและฐานข้อมูลเหล่านี้ ในทางกลับกันมีวิธีเขียนโค้ดด้วยตนเองแล้วสร้างฐานข้อมูลโดยอัตโนมัติ
อดีตเรียกว่า "ฐานข้อมูลก่อน" และหลังเรียกว่า "โค้ดก่อน" นอกจากนี้ยังมี "model-first" ซึ่งสร้างโค้ดและฐานข้อมูลจากพิมพ์เขียว เช่น ไดอะแกรม ER แต่ไม่ได้ใช้กันอย่างแพร่หลายใน Entity Framework Core
ในกรณีนี้ เราจะใช้รูปแบบ "ฐานข้อมูลก่อน" ที่สร้างโค้ดบนสมมติฐานที่ว่าฐานข้อมูลมีอยู่แล้ว
การตั้งค่า SQL Server
ในการเข้าถึงฐานข้อมูล SQL Server ในเคล็ดลับนี้โปรดตั้งค่า SQL Server ล่วงหน้า สามารถตั้งค่าบนพีซีในสภาพแวดล้อมการพัฒนาหรือบนพีซีเครื่องอื่นผ่านเครือข่าย หากคุณสามารถเชื่อมต่อกับ SQL Server จากสภาพแวดล้อมการพัฒนาของคุณ คุณก็พร้อมที่จะไป ในเคล็ดลับนี้ SQL Server จะถูกติดตั้งในสภาพแวดล้อมที่แยกต่างหาก
ขั้นตอนการตั้งค่า SQL Server ถูกละเว้นเนื่องจากมีความซ้ําซ้อน หน้าต่อไปนี้มีเคล็ดลับที่เกี่ยวข้องกับ SQL Server ดังนั้นหากคุณต้องการทราบวิธีตั้งค่าโปรดดู
สร้างตาราง
คราวนี้เราจะสร้างฐานข้อมูลและตารางต่อไปนี้เป็น Mr./Ms.
- ชื่อฐานข้อมูล: TestDatabase
- ชื่อตาราง: ผู้ใช้
- คอลัมน์ตาราง: [ID], [ชื่อ], [รหัสผ่าน], [อายุ], [อีเมล], [วันเกิด], [UpdateDateTime]
คุณสามารถสร้างได้ด้วยวิธีใดก็ได้ แต่ถ้าคุณไม่ต้องการทํา ให้เรียกใช้ SQL ต่อไปนี้กับ SQL Server เพื่อสร้าง
ต่อไปนี้เป็น SQL การสร้างฐานข้อมูล แต่เนื่องจากเส้นทางของการสร้างฐานข้อมูลเปลี่ยนไปตามเวอร์ชัน ฯลฯ จึงอาจเชื่อถือได้มากกว่าที่จะสร้างด้วย GUI หรือคําสั่งแทน SQL
USE [master]
GO
CREATE DATABASE [TestDatabase]
CONTAINMENT = NONE
ON PRIMARY
( NAME = N'TestDatabase', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA\TestDatabase.mdf' , SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 65536KB )
LOG ON
( NAME = N'TestDatabase_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA\TestDatabase_log.ldf' , SIZE = 8192KB , MAXSIZE = 2048GB , FILEGROWTH = 65536KB )
WITH CATALOG_COLLATION = DATABASE_DEFAULT, LEDGER = OFF
GO
ALTER DATABASE [TestDatabase] SET COMPATIBILITY_LEVEL = 160
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [TestDatabase].[dbo].[sp_fulltext_database] @action = 'enable'
end
GO
ALTER DATABASE [TestDatabase] SET ANSI_NULL_DEFAULT OFF
GO
ALTER DATABASE [TestDatabase] SET ANSI_NULLS OFF
GO
ALTER DATABASE [TestDatabase] SET ANSI_PADDING OFF
GO
ALTER DATABASE [TestDatabase] SET ANSI_WARNINGS OFF
GO
ALTER DATABASE [TestDatabase] SET ARITHABORT OFF
GO
ALTER DATABASE [TestDatabase] SET AUTO_CLOSE OFF
GO
ALTER DATABASE [TestDatabase] SET AUTO_SHRINK OFF
GO
ALTER DATABASE [TestDatabase] SET AUTO_UPDATE_STATISTICS ON
GO
ALTER DATABASE [TestDatabase] SET CURSOR_CLOSE_ON_COMMIT OFF
GO
ALTER DATABASE [TestDatabase] SET CURSOR_DEFAULT GLOBAL
GO
ALTER DATABASE [TestDatabase] SET CONCAT_NULL_YIELDS_NULL OFF
GO
ALTER DATABASE [TestDatabase] SET NUMERIC_ROUNDABORT OFF
GO
ALTER DATABASE [TestDatabase] SET QUOTED_IDENTIFIER OFF
GO
ALTER DATABASE [TestDatabase] SET RECURSIVE_TRIGGERS OFF
GO
ALTER DATABASE [TestDatabase] SET DISABLE_BROKER
GO
ALTER DATABASE [TestDatabase] SET AUTO_UPDATE_STATISTICS_ASYNC OFF
GO
ALTER DATABASE [TestDatabase] SET DATE_CORRELATION_OPTIMIZATION OFF
GO
ALTER DATABASE [TestDatabase] SET TRUSTWORTHY OFF
GO
ALTER DATABASE [TestDatabase] SET ALLOW_SNAPSHOT_ISOLATION OFF
GO
ALTER DATABASE [TestDatabase] SET PARAMETERIZATION SIMPLE
GO
ALTER DATABASE [TestDatabase] SET READ_COMMITTED_SNAPSHOT OFF
GO
ALTER DATABASE [TestDatabase] SET HONOR_BROKER_PRIORITY OFF
GO
ALTER DATABASE [TestDatabase] SET RECOVERY FULL
GO
ALTER DATABASE [TestDatabase] SET MULTI_USER
GO
ALTER DATABASE [TestDatabase] SET PAGE_VERIFY CHECKSUM
GO
ALTER DATABASE [TestDatabase] SET DB_CHAINING OFF
GO
ALTER DATABASE [TestDatabase] SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF )
GO
ALTER DATABASE [TestDatabase] SET TARGET_RECOVERY_TIME = 60 SECONDS
GO
ALTER DATABASE [TestDatabase] SET DELAYED_DURABILITY = DISABLED
GO
ALTER DATABASE [TestDatabase] SET ACCELERATED_DATABASE_RECOVERY = OFF
GO
EXEC sys.sp_db_vardecimal_storage_format N'TestDatabase', N'ON'
GO
ALTER DATABASE [TestDatabase] SET QUERY_STORE = ON
GO
ALTER DATABASE [TestDatabase] SET QUERY_STORE (OPERATION_MODE = READ_WRITE, CLEANUP_POLICY = (STALE_QUERY_THRESHOLD_DAYS = 30), DATA_FLUSH_INTERVAL_SECONDS = 900, INTERVAL_LENGTH_MINUTES = 60, MAX_STORAGE_SIZE_MB = 1000, QUERY_CAPTURE_MODE = AUTO, SIZE_BASED_CLEANUP_MODE = AUTO, MAX_PLANS_PER_QUERY = 200, WAIT_STATS_CAPTURE_MODE = ON)
GO
ALTER DATABASE [TestDatabase] SET READ_WRITE
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
การตั้งค่า Visual Studio
เราถือว่าคุณได้ตั้งค่านี้ไว้แล้วเช่นกัน หากคุณต้องการทราบขั้นตอนการตั้งค่า ฯลฯ จะสรุปไว้ในหน้าต่อไปนี้
สร้างโครงการ
Entity Framework Core ไม่ได้ขึ้นอยู่กับสภาพแวดล้อมการดําเนินการใด ๆ ดังนั้นจึงสามารถใช้ในหลายโครงการ ในบทความนี้ เราจะใช้ Entity Framework Core ในสภาพแวดล้อมแอปพลิเคชันคอนโซลอย่างง่าย
ในโปรเจ็กต์ใหม่ ให้เลือก แอปคอนโซล
โครงการถูกสร้างขึ้นแล้ว ไม่สําคัญว่าชื่อโครงการคืออะไร
รับแพคเกจ Entity Framework Core
รับแพคเกจสําหรับการใช้ Entity Framework Core กับ NuGet
คลิกขวาที่การขึ้นต่อกัน แล้วเลือก จัดการแพคเกจ NuGet
เมื่อเลือก "เรียกดู" จากแท็บ ให้ป้อนในช่อง EntityFrameworkCore
ค้นหา จากนั้น คุณควรเห็นแพคเกจที่เกี่ยวข้องกับ Entity Framework Core ในรายการ
เนื่องจากเราจะใช้ SQL Server ในครั้งนี้เราจะติดตั้งแพ็คเกจต่อไปนี้
- Microsoft.EntityFrameworkCore
- Microsoft.EntityFrameworkCore.Tools
- Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore
ในตัวอย่างนี้เรากําลังติดตั้ง . ติดตั้งอีกสองตัวด้วย
เลือกเป้าหมายการติดตั้งและคลิกปุ่มติดตั้ง สําหรับเวอร์ชัน ให้เลือกเสถียรล่าสุด
กล่องโต้ตอบโดยทั่วไปก็โอเค และคุณสามารถคลิก ตกลง
ติดตั้งอีกสองตัวด้วย
ฉันคิดว่าแพ็คเกจมีลักษณะดังนี้:
สร้างแบบจําลอง (รหัส) จากโครงสร้างตารางฐานข้อมูล
เมื่อต้องการสร้างโมเดลและโค้ดอื่นๆ โดยอัตโนมัติ ก่อนอื่นให้สร้างโปรเจ็กต์เพื่อให้แน่ใจว่าไม่มีข้อผิดพลาด หากมีข้อผิดพลาด การสร้างแบบจําลองล้มเหลว หากคุณยืนยันแล้วว่าไม่มีข้อผิดพลาด คุณไม่จําเป็นต้องสร้าง
จาก Visual Studio ให้เปิดคอนโซลตัวจัดการแพคเกจ หากคุณไม่มี คุณสามารถเปิดได้จากเมนู "เครื่องมือ", "ตัวจัดการแพ็คเกจ NuGet", "คอนโซลตัวจัดการแพ็คเกจ"
หน้าต่างต่อไปนี้จะปรากฏขึ้นดังนั้นตรวจสอบให้แน่ใจว่า "โครงการเริ่มต้น" ที่มุมขวาบนเป็นโครงการที่คุณต้องการสร้างแบบจําลอง (คุณต้องระมัดระวังหากคุณมีหลายโครงการ)
ป้อนข้อความต่อไปนี้ในช่องป้อนข้อมูล: พารามิเตอร์จะเปลี่ยนไปตามสภาพแวดล้อม ดังนั้นโปรดเปลี่ยนตามคําอธิบายต่อไปนี้ในเวลาที่เหมาะสม
Scaffold-DbContext -Provider Microsoft.EntityFrameworkCore.SqlServer -Connection "Data Source=<サーバー名>\<インスタンス名>;Database=<データメース名>;user id=<接続ユーザー名>;password=<接続パスワード>;TrustServerCertificate=true" -f -OutputDir "<出力フォルダパス>" -Context "<コンテキストクラス名>" -UseDatabaseNames -DataAnnotations -NoPluralize
ตัวอย่างอินพุต
Scaffold-DbContext -Provider Microsoft.EntityFrameworkCore.SqlServer -Connection "Data Source=TestServer;Database=TestDatabase;user id=TestUser;password=pass;TrustServerCertificate=true" -f -OutputDir "Models\Database" -Context "TestDatabaseDbContext" -UseDatabaseNames -DataAnnotations -NoPluralize
คําอธิบายพารามิเตอร์ | ตัวอย่างพารามิเตอร์ | |
---|---|---|
ผู้จัดหา | สําหรับ SQL Server ได้รับการ Microsoft.EntityFrameworkCore.SqlServer แก้ไข |
Microsoft.EntityFrameworkCore.SqlServer |
การเชื่อมต่อ | สตริงการเชื่อมต่อเพื่อเชื่อมต่อกับฐานข้อมูล สตริงการเชื่อมต่อสามารถใช้ร่วมกับแอพอื่น ๆ ได้ดังนั้นโปรดปฏิบัติตามสัญกรณ์ของสตริงการเชื่อมต่อสําหรับเนื้อหาที่จะระบุ คุณสามารถใช้การรับรองความถูกต้องของ Windows หรือการรับรองความถูกต้องของ SQL Server อย่างไรก็ตามจะใช้ชั่วคราวเพื่อสร้างแบบจําลองเท่านั้นดังนั้นจึงไม่จําเป็นต้องตระหนักถึงความปลอดภัยหลังจากเผยแพร่แอปพลิเคชันสําหรับสตริงการเชื่อมต่อนี้ หากคุณมีสัญลักษณ์ในรหัสผ่าน โปรดระวังการหลบหนี | "แหล่งข้อมูล=ServerName\SQLEXPRESS; ฐานข้อมูล=TestDatabase; รหัสผู้ใช้=ชื่อผู้ใช้; รหัสผ่าน=**********" |
f | แม้ว่าโปรแกรมจะมีอยู่แล้ว แต่ก็จะถูกบังคับเขียนทับ | ไม่มี<> |
เอาต์พุต | เส้นทางโฟลเดอร์ที่คุณต้องการส่งออกโค้ด เส้นทางที่สัมพันธ์กับโฟลเดอร์โครงการ | โมเดล\ฐานข้อมูล |
บริบท | ชื่อคลาสบริบทเมื่อใช้ Entity Framework | TestDatabaseDbContext |
UseDatabaseNames | หากระบุชื่อตารางของฐานข้อมูลจะเป็นชื่อคลาสตามที่เป็นอยู่ หากไม่ได้ระบุ กรณีของชื่อคลาสเอนทิตีจะถูกปรับตามกฎ | ไม่มี<> |
คําอธิบายประกอบข้อมูล | เมื่อระบุ ชนิดคอลัมน์จะผนวกแอตทริบิวต์ DataAnnotation ให้กับแต่ละคุณสมบัติโดยอัตโนมัติ สิ่งนี้มีประโยชน์เล็กน้อยหากคุณต้องการทําการตรวจสอบอินพุตโดยอัตโนมัติตามประเภทของฐานข้อมูล | ไม่มี<> |
เนมสเปซ | เนมสเปซที่คลาสเอนทิตีที่สร้างขึ้นเป็นอยู่ หากไม่ได้ระบุ namespace จะถูกกําหนดตามโฟลเดอร์ | TestNamespace |
ContextNamespace | เนมสเปซที่บริบทที่สร้างขึ้นเป็นอยู่ หากไม่ได้ระบุ namespace จะถูกกําหนดตามโฟลเดอร์ | TestNamespace |
NoOn การกําหนดค่า | อย่าฝังสตริงการเชื่อมต่อดิบในโค้ดของคุณ | ไม่มี<> |
ไม่พหูพจน์ | ตรวจสอบให้แน่ใจว่า ชื่อคุณสมบัติสําหรับแต่ละชื่อตารางในบริบทไม่ได้เป็นพหูพจน์ | ไม่มี<> |
เมื่อคุณกด Enter เพื่อเรียกใช้รหัสจะถูกสร้างขึ้นโดยอัตโนมัติ: หากเกิดข้อผิดพลาด เหตุผลจะปรากฏขึ้น ดังนั้นโปรดตอบกลับตามเนื้อหาของข้อผิดพลาด
User
รหัสรุ่นของตารางมีดังนี้
using System.ComponentModel.DataAnnotations;
namespace SetupSqlServerDatabaseFirst.Models.Database;
public partial class User
{
[Key]
public int ID { get; set; }
[StringLength(20)]
public string Name { get; set; } = null!;
[StringLength(20)]
public string Password { get; set; } = null!;
public int? Age { get; set; }
[StringLength(200)]
public string? Email { get; set; }
public DateOnly? Birthday { get; set; }
public DateTime? UpdateDateTime { get; set; }
}
อย่างไรก็ตามคําเตือนจะปรากฏขึ้นเนื่องจากสตริงการเชื่อมต่อถูกเขียนตามที่เป็นอยู่ในรหัสของคลาสบริบทที่สร้างขึ้น ถ้าเป็นไปได้ควรเก็บสตริงการเชื่อมต่อไว้ในที่แยกต่างหากและตั้งค่าเมื่อรันไทม์ แต่ในกรณีนี้มีวัตถุประสงค์เพื่อตรวจสอบการทํางานดังนั้นฉันจะปล่อยทิ้งไว้เหมือนเดิม
ลองดึงข้อมูลและแสดงระเบียน
ตอนนี้เรามีรหัสสําหรับเข้าถึงระเบียนในฐานข้อมูลแล้ว ลองดึงระเบียนและแสดงบนคอนโซลกัน
Program.cs
และแก้ไขดังนี้
// See https://aka.ms/new-console-template for more information
using SetupSqlServerDatabaseFirst.Models.Database;
using System.Text.Json;
Console.WriteLine("Hello, World!");
// データベースコンテキストのインスタンスを生成する
using var dbContext = new TestDatabaseDbContext();
// データベースから User 一覧を取得する
var users = dbContext.User.ToList();
// 取得した User 情報をコンソールに書き出す
foreach (var user in users)
{
Console.WriteLine(JsonSerializer.Serialize(user));
}
สร้างคลาสnew
ที่สร้างขึ้นโดยอัตโนมัติDbContext
ใน มีการประกาศเพื่อให้สามารถทําลายการเชื่อมต่อฐานข้อมูลusing var
ได้โดยอัตโนมัติ
dbContext
สร้างคุณสมบัติเพื่อเข้าถึงแต่ละโมเดล ดังนั้นในกรณีนี้ User
คุณสามารถจัดการเรกคอร์ดในตารางได้โดยการเข้าถึง User
คุณสมบัติ
SQL ที่ออกจะถูกสร้างขึ้นโดยอัตโนมัติภายในและไม่จําเป็นต้องสังเกตเห็น
ToList
ที่นี่วิธีการขยายจะใช้เพื่อUser
ดึงระเบียนทั้งหมดในตาราง
foreach
ส่วนที่เหลือทําได้โดยใช้วิธีการ และ JsonSerializer.Serialize
เพื่อUser
แสดงข้อมูลบนคอนโซล
ดังที่ได้User
กล่าวไว้ข้างต้นแต่ละคอลัมน์ในตารางจะถูกประกาศเป็นคุณสมบัติดังนั้นจึงเป็นไปได้ที่จะดึงค่าทีละรายการ