Bersedia untuk mengakses SQL Server menggunakan Teras Rangka Kerja Entiti (pangkalan data didahulukan)

Laman dikemaskini :
Tarikh penciptaan halaman :

Persekitaran operasi

Visual Studio
  • Visual Studio 2022
.BERSIH
  • .NET 8
Teras Rangka Kerja Entiti
  • Teras Rangka Kerja Entiti 8.0
Pelayan SQL
  • SQL Server 2022

* Di atas ialah persekitaran pengesahan, tetapi ia mungkin berfungsi dengan versi lain.

Pada mulanya

Teras Rangka Kerja Entiti ialah perpustakaan pemeta O/R. Apabila mengakses pangkalan data, anda boleh mengakses rekod pangkalan data melalui model (kelas) yang ditakrifkan dalam kod, tanpa menggunakan pernyataan SQL secara langsung. Ini memberikan faedah berikut:

  • Oleh kerana pernyataan SQL tidak ditulis secara langsung, risiko keselamatan seperti suntikan SQL dikurangkan.
  • Memandangkan pernyataan SQL ialah rentetan, walaupun anda membuat kesilapan dalam sintaks, ia tidak diperiksa untuk ralat binaan, tetapi kerana model ialah sintaks program, anda boleh menyemak kesilapan pada masa binaan.

Teras Rangka Kerja Entiti boleh menjana kod secara automatik daripada pangkalan data sedia ada untuk menyambung kepada model dan pangkalan data ini. Sebaliknya, terdapat cara untuk menulis kod secara manual dan kemudian menjana pangkalan data secara automatik.

Yang pertama dipanggil "pangkalan data pertama" dan yang kedua dipanggil "kod pertama". Terdapat juga "model-first", yang menjana kod dan pangkalan data daripada pelan tindakan seperti gambar rajah ER, tetapi ia tidak digunakan secara meluas dalam Entity Framework Core.

Dalam kes ini, kami akan menggunakan corak "pangkalan data pertama" yang menjana kod dengan andaian bahawa pangkalan data sudah wujud.

Persediaan SQL Server

Untuk mengakses pangkalan data SQL Server dalam petua ini, sila sediakan SQL Server terlebih dahulu. Ia boleh disediakan pada PC dalam persekitaran pembangunan atau pada PC lain melalui rangkaian. Jika anda boleh menyambung ke SQL Server daripada persekitaran pembangunan anda, anda boleh pergi. Dalam petua ini, SQL Server dipasang dalam persekitaran yang berasingan.

Langkah persediaan SQL Server ditinggalkan kerana ia berlebihan. Halaman berikut mengandungi petua berkaitan SQL Server, jadi jika anda ingin mengetahui cara menyediakannya, sila rujuknya.

Buat jadual

Kali ini, kami akan membuat pangkalan data dan jadual berikut sebagai Encik / Cik

  • Nama pangkalan data: TestDatabase
  • Nama jadual: Pengguna
  • Lajur jadual: [ID], [Nama], [Kata Laluan], [Umur], [E-mel], [Hari Lahir], [UpdateDateTime]

Anda boleh menciptanya dalam apa jua cara, tetapi jika anda tidak mahu melakukannya, jalankan SQL berikut terhadap SQL Server untuk menjananya.

Berikut ialah penciptaan pangkalan data SQL, tetapi memandangkan laluan penciptaan pangkalan data berubah bergantung pada versi, dsb., ia mungkin lebih dipercayai untuk menciptanya dengan GUI atau arahan dan bukannya 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 penciptaan jadual.

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

Rekod Lampiran 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

Persediaan Visual Studio

Kami menganggap bahawa anda telah menyediakannya juga. Jika anda ingin mengetahui prosedur persediaan, dsb., ia diringkaskan pada halaman berikut.

Buat projek

Teras Rangka Kerja Entiti tidak bergantung pada mana-mana persekitaran pelaksanaan tertentu, jadi ia boleh digunakan dalam banyak projek. Dalam artikel ini, kami akan menggunakan Teras Rangka Kerja Entiti dalam persekitaran aplikasi konsol yang mudah.

Dalam projek baharu, pilih Aplikasi Konsol.

Projek ini telah diwujudkan. Tidak kira apa nama projeknya.

Dapatkan pakej Teras Rangka Kerja Entiti

Dapatkan pakej untuk menggunakan Teras Rangka Kerja Entiti dengan NuGet.

Klik kanan pergantungan dan pilih Urus Pakej NuGet.

Dengan "Layari" dipilih daripada tab, masukkan dalam EntityFrameworkCore medan carian. Anda kemudiannya akan melihat pakej berkaitan Teras Rangka Kerja Entiti dalam senarai.

Memandangkan kami akan menggunakan SQL Server kali ini, kami akan memasang pakej berikut.

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

Microsoft.EntityFrameworkCore Dalam contoh ini, kami memasang . Pasang dua yang lain juga.

Pilih sasaran pemasangan dan klik butang Pasang. Untuk versi, pilih stabil terkini.

Dialog pada asasnya OK dan anda boleh klik OK.

Pasang dua yang lain juga.

Saya rasa pakejnya kelihatan seperti ini:

Cipta model (kod) daripada struktur jadual pangkalan data

Untuk memastikan model dan kod lain dijana secara automatik, mula-mula bina projek untuk memastikan tiada ralat. Sekiranya terdapat ralat, penciptaan model gagal. Jika anda telah mengesahkan bahawa tiada ralat, anda tidak perlu membinanya.

Daripada Visual Studio, buka Konsol Pengurus Pakej. Jika anda tidak mempunyai satu, anda boleh membukanya daripada menu "Alat", "Pengurus Pakej NuGet", "Konsol Pengurus Pakej".

Tetingkap berikut akan dipaparkan, jadi pastikan bahawa "Projek Lalai" di sudut kanan atas ialah projek yang anda ingin buat model. (Anda perlu berhati-hati jika anda mempunyai banyak projek)

Masukkan teks berikut dalam medan input: Parameter berubah bergantung kepada persekitaran, jadi sila ubahnya mengikut penjelasan berikut tepat pada masanya.

Scaffold-DbContext -Provider Microsoft.EntityFrameworkCore.SqlServer -Connection "Data Source=<サーバー名>\<インスタンス名>;Database=<データメース名>;user id=<接続ユーザー名>;password=<接続パスワード>;TrustServerCertificate=true" -f -OutputDir "<出力フォルダパス>" -Context "<コンテキストクラス名>" -UseDatabaseNames -DataAnnotations -NoPluralize

Contoh Input

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
Penerangan parameterContoh parameter
Pembekal Untuk SQL Server, ia Microsoft.EntityFrameworkCore.SqlServer telah ditetapkan. Microsoft.EntityFrameworkCore.SqlServer
Sambungan Rentetan sambungan untuk menyambung ke pangkalan data. Rentetan sambungan boleh digunakan sama dengan apl lain, jadi sila ikut notasi rentetan sambungan untuk kandungan yang akan ditentukan. Anda boleh menggunakan sama ada Pengesahan Windows atau Pengesahan SQL Server. Dengan cara ini, ia hanya digunakan buat sementara waktu untuk membuat model, jadi tidak perlu mengetahui keselamatan selepas menerbitkan aplikasi untuk rentetan sambungan ini. Jika anda mempunyai simbol dalam kata laluan anda, berhati-hati daripada melarikan diri. "Sumber Data=ServerName\SQLEXPRESS; Pangkalan Data=Pangkalan Data Ujian; id pengguna=Nama Pengguna; kata laluan=**********"
f Walaupun program itu sudah wujud, ia akan ditulis ganti secara paksa. Tiada <>
Pengarah Keluaran Laluan folder di mana anda ingin mengeluarkan kod. Laluan relatif kepada folder projek Model\Pangkalan Data
Konteks Nama Kelas Konteks Apabila Menggunakan Rangka Kerja Entiti TestDatabaseDbContext
UseDatabaseNames Jika ditentukan, nama jadual pangkalan data akan menjadi nama kelas seperti sedia ada. Jika tidak dinyatakan, kes nama kelas entiti diselaraskan mengikut peraturan. Tiada <>
Anotasi Data Apabila ditentukan, jenis lajur secara automatik menambahkan atribut DataAnnotation kepada setiap sifat. Ini agak berguna jika anda ingin melakukan semakan input secara automatik mengikut jenis pangkalan data. Tiada <>
Ruang nama Ruang nama yang dimiliki kelas entiti yang dijana. Jika tidak ditentukan, ruang nama ditentukan mengikut folder. TestNamespace
ContextNamespace Ruang nama yang dimiliki oleh Konteks yang dijana. Jika tidak ditentukan, ruang nama ditentukan mengikut folder. TestNamespace
NoOnMengkonfigurasi Jangan benamkan rentetan sambungan mentah dalam kod anda. Tiada <>
NoPluralize Pastikan nama sifat untuk setiap nama jadual dalam Konteks tidak jamak. Tiada <>

Apabila anda menekan Enter untuk menjalankannya, kod dijana secara automatik: Sekiranya ralat berlaku, sebabnya akan dipaparkan, jadi sila balas mengikut kandungan ralat.

User Kod model jadual adalah seperti berikut.

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

Dengan cara ini, amaran dipaparkan kerana rentetan sambungan ditulis seperti dalam kod kelas konteks yang dihasilkan. Sekiranya boleh, rentetan sambungan harus disimpan di tempat yang berasingan dan ditetapkan pada masa jalan, tetapi dalam kes ini, ia adalah untuk tujuan memeriksa operasi, jadi saya akan membiarkannya seperti itu.

Cuba dapatkan semula dan paparkan rekod

Memandangkan kita mempunyai kod untuk mengakses rekod dalam pangkalan data, mari cuba mendapatkan semula rekod dan memaparkannya pada konsol.

Program.cs dan ubah suainya seperti berikut.

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

Jana kelas new yang dijana DbContext secara automatik dalam . Ia diisytiharkan supaya sambungan pangkalan data boleh using var dimusnahkan secara automatik.

dbContext menjana sifat untuk mengakses setiap model, jadi dalam kes User ini, anda boleh memanipulasi rekod dalam jadual dengan User mengakses sifat. SQL yang dikeluarkan dijana secara automatik secara dalaman dan tidak perlu diperhatikan.

ToList Di sini, kaedah sambungan digunakan untuk User mendapatkan semua rekod dalam jadual.

foreach Selebihnya dilakukan menggunakan kaedah dan untuk JsonSerializer.Serialize User memaparkan maklumat pada konsol. Seperti yang User dinyatakan di atas, setiap lajur dalam jadual diisytiharkan sebagai sifat, jadi adalah mungkin untuk mendapatkan nilai secara individu.