準備使用 Entity Framework Core(資料庫優先)訪問 SQL ServerPrepare to access SQL Server using Entity Framework Core (database-first)

更新頁 :
頁面創建日期 :

操作環境

Visual Studio的
  • Visual Studio 2022
。網
  • .NET 8
實體框架核心
  • 實體框架核心 8.0
SQL 伺服器
  • SQL Server 2022

* 以上是一個驗證環境,但它可能適用於其他版本。

起先

Entity Framework Core 是一個 O/R 映射器庫。 在訪問資料庫時,您可以通過代碼中定義的模型(類)訪問資料庫的記錄,而無需直接使用SQL語句。 這提供了以下好處:

  • 由於SQL語句不是直接編寫的,因此減少了SQL注入等安全風險。
  • 由於 SQL 語句是字串,因此即使語法錯誤,也不會檢查構建錯誤,但由於模型是程式語法,因此可以在構建時檢查錯誤。

Entity Framework Core 可以從現有資料庫自動生成代碼,以連接到這些模型和資料庫。 相反,有一種方法可以手動編寫代碼,然後自動生成資料庫。

前者稱為「資料庫優先」,後者稱為“代碼優先”。 還有「模型優先」,它從 ER 圖等藍圖生成代碼和資料庫,但它在 Entity Framework Core 中並未廣泛使用。

在本例中,我們將使用「資料庫優先」模式,該模式在資料庫已存在的基礎上生成代碼。

SQL Server 設置

為了訪問此提示中的 SQL Server 資料庫,請提前設置 SQL Server。 它可以在開發環境中的PC上設置,也可以通過網路在另一台PC上設置。 如果可以從開發環境連接到 SQL Server,那麼就可以開始了。 在此提示中,SQL Server 安裝在單獨的環境中。

SQL Server 設置步驟被省略,因為它們是冗餘的。 以下頁面包含與 SQL Server 相關的提示,因此,如果您想瞭解如何設置它,請參考它。

創建表

這一次,我們將以 Mr./Ms. 的身份創建以下資料庫和表。

  • 資料庫名稱:TestDatabase
  • 表名:使用者
  • 表列:[ID]、[名稱]、[密碼]、[年齡]、[電子郵件]、[生日]、[UpdateDateTime]

您可以以任何方式創建它,但如果您不想這樣做,請針對 SQL Server 運行以下 SQL 來生成它。

以下是資料庫創建 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; Database=TestDatabase; 使用者 id=使用者名; 密碼=**********”
f 即使程式已經存在,它也會被強行覆蓋。 沒有<>
輸出目錄 要輸出代碼的資料夾路徑。 相對於專案資料夾的路徑 模型\資料庫
上下文 使用實體框架時的上下文類名稱 TestDatabaseDbContext
UseDatabaseNames(使用資料庫名稱) 如果指定,則資料庫的表名將按原樣為類名。 如果未指定,則根據規則調整實體類名的大小寫。 沒有<>
DataAnnotations 指定后,列類型會自動將 DataAnnotation 特性追加到每個屬性。 如果您想根據資料庫類型自動執行輸入檢查,這將有點用。 沒有<>
Namespace 生成的實體類所屬的命名空間。 如果未指定,則根據資料夾確定命名空間。 Test命名空間
Context命名空間 生成的Context所屬的命名空間。 如果未指定,則根據資料夾確定命名空間。 Test命名空間
NoOnConfiguring 不要在代碼中嵌入原始連接字串。 沒有<>
NoPluralize 確保 Context 中每個表名的屬性名稱不是複數形式。 沒有<>

當您按 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));
}

在中生成自動生成的 DbContextnew 。 它被聲明為可以自動銷毀資料庫連接 using var

dbContext 生成屬性以存取每個模型,因此在本例 User 中,您可以通過訪問屬性來 User 操作表中的記錄。 發出的 SQL 是內部自動生成的,不需要注意。

ToList這裡,使用擴展方法來User檢索表中的所有記錄。

foreach其餘部分是使用 and JsonSerializer.Serialize 方法User在控制台上顯示資訊來完成的。 如User上所述,表中的每一列都聲明為一個屬性,因此可以單獨檢索該值。