MiniAPI(十二)：EntityFrameworkの導入

この記事では、MiniAPIにEntityFrameworkを導入する方法について重点的に説明します。EntityFrameworkの使用方法については本記事の重点ではありません。
MiniAPIでEntityFrameworkを使用するためには、まず、SQL Server用のデータ作成スクリプトから始めます。データベースはSQL Serverを使用し、バージョンによっては問題が発生する可能性がありますので、必要に応じて調整してください。こちらのスクリプトはSQL Server 2019を基にしています。

以下、SQL Server用のデータ作成スクリプトの抜粋です。
```sql

USE [Exam]
GO
/****** Object:  Table [dbo].[Answers]    Script Date: 2022/1/22 10:01:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Answers](
  [ID] [int] IDENTITY(1,1) NOT NULL,
  [Sequre] [nvarchar](8) NOT NULL,
  [Answer] [nvarchar](200) NOT NULL,
  [IsTrue] [bit] NOT NULL,
  [QuestionID] [int] NOT NULL,
 CONSTRAINT [PK_Answers] PRIMARY KEY CLUSTERED 
(
  [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[ExamPaperQuestions]    Script Date: 2022/1/22 10:01:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ExamPaperQuestions](
  [ExamPaperID] [int] NOT NULL,
  [QuestionID] [int] NOT NULL,
 CONSTRAINT [PK_ExamPaperQuestions_1] PRIMARY KEY CLUSTERED 
(
  [ExamPaperID] ASC,
  [QuestionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[ExamPapers]    Script Date: 2022/1/22 10:01:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ExamPapers](
  [ID] [int] IDENTITY(1,1) NOT NULL,
  [Title] [nvarchar](200) NOT NULL,
  [Memo] [nvarchar](1000) NULL,
  [CreateTime] [datetime2](7) NOT NULL,
 CONSTRAINT [PK_ExamPapers] PRIMARY KEY CLUSTERED 
(
  [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[Questions]    Script Date: 2022/1/22 10:01:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Questions](
  [ID] [int] IDENTITY(1,1) NOT NULL,
  [Question] [nvarchar](300) NOT NULL,
  [Score] [float] NOT NULL,
  [QuestionTypeID] [int] NOT NULL,
  [SujectTypeID] [int] NOT NULL,
 CONSTRAINT [PK_Questions] PRIMARY KEY CLUSTERED 
(
  [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[QuestionTypes]    Script Date: 2022/1/22 10:01:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[QuestionTypes](
  [ID] [int] IDENTITY(1,1) NOT NULL,
  [TypeName] [nvarchar](50) NOT NULL,
 CONSTRAINT [PK_QuestionTypes] PRIMARY KEY CLUSTERED 
(
  [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[SubjectTypes]    Script Date: 2022/1/22 10:01:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[SubjectTypes](
  [ID] [int] IDENTITY(1,1) NOT NULL,
  [TypeName] [nvarchar](50) NOT NULL,
 CONSTRAINT [PK_SubjectTypes] PRIMARY KEY CLUSTERED 
(
  [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[UserExamAnswers]    Script Date: 2022/1/22 10:01:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UserExamAnswers](
  [ID] [int] IDENTITY(1,1) NOT NULL,
  [UserExamID] [int] NOT NULL,
  [AnswerID] [int] NOT NULL,
  [CreateTime] [datetime] NOT NULL,
 CONSTRAINT [PK_UserExamAnswers] PRIMARY KEY CLUSTERED 
(
  [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[UserExams]    Script Date: 2022/1/22 10:01:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UserExams](
  [ID] [int] IDENTITY(1,1) NOT NULL,
  [UserID] [int] NOT NULL,
  [ExamPapgerID] [int] NOT NULL,
  [BeginTime] [datetime] NOT NULL,
  [EndTime] [datetime] NOT NULL,
 CONSTRAINT [PK_UserExams] PRIMARY KEY CLUSTERED 
(
  [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[Users]    Script Date: 2022/1/22 10:01:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Users](
  [ID] [int] IDENTITY(1,1) NOT NULL,
  [UserName] [nvarchar](50) NOT NULL,
  [Password] [nvarchar](50) NOT NULL,
  [Salt] [nvarchar](50) NOT NULL,
  [Name] [nvarchar](50) NOT NULL,
  [Tel] [varchar](11) NULL,
 CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED 
(
  [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[Answers] ON 

INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (1, N'A', N'循环', 0, 1)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (2, N'B', N'指针 ', 1, 1)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (3, N'C', N'判断 ', 0, 1)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (4, N'D', N'数组', 0, 1)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (5, N'A', N'只读', 1, 2)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (6, N'B', N'只写', 0, 2)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (7, N'C', N'可读写', 0, 2)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (8, N'D', N'不可读不可写', 0, 2)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (9, N'A', N'break', 1, 3)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (10, N'B', N'goto', 0, 3)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (11, N'C', N'return ', 0, 3)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (12, N'D', N'continue', 0, 3)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (13, N'A', N'class', 0, 4)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (14, N'B', N'using', 1, 4)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (16, N'D', N'this', 0, 4)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (17, N'A', N'click', 0, 5)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (18, N'B', N'catch', 0, 5)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (19, N'C', N'try', 1, 5)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (20, N'D', N'show', 0, 5)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (21, N'A', N'该复选框被选中', 1, 6)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (22, N'B', N'该复选框不被选中', 0, 6)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (23, N'C', N'不显示该复选框的文本信息', 0, 6)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (24, N'D', N'显示该复选框的文本信息', 0, 6)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (25, N'A', N'System', 0, 7)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (26, N'B', N'System.Data', 0, 7)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (27, N'C', N'System.Data.OleDb', 0, 7)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (28, N'D', N'System.Data.SqlClient', 1, 7)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (29, N'A', N'FileStream类 ', 1, 8)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (30, N'B', N'StreamReade', 0, 8)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (31, N'C', N'BinaryWriter类', 0, 8)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (32, N'D', N'BinaryReader', 0, 8)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (33, N'A', N'输入、编译、运行', 1, 9)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (34, N'B', N'编译、连接、运行', 0, 9)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (35, N'C', N'输入、运行、编辑', 0, 9)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (36, N'D', N'编辑、编译、连接', 0, 9)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (37, N'A', N'int转换成short', 0, 10)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (38, N'B', N'short转换成long', 0, 10)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (39, N'C', N'char转换成int', 0, 10)
INSERT [dbo].[Answers] ([ID], [Sequre], [Answer], [IsTrue], [QuestionID]) VALUES (40, N'D', N'bytes转换成float', 1, 10)
SET IDENTITY_INSERT [dbo].[Answers] OFF
GO
INSERT [dbo].[ExamPaperQuestions] ([ExamPaperID], [QuestionID]) VALUES (1, 1)
INSERT [dbo].[ExamPaperQuestions] ([ExamPaperID], [QuestionID]) VALUES (1, 2)
INSERT [dbo].[ExamPaperQuestions] ([ExamPaperID], [QuestionID]) VALUES (1, 3)
INSERT [dbo].[ExamPaperQuestions] ([ExamPaperID], [QuestionID]) VALUES (1, 4)
INSERT [dbo].[ExamPaperQuestions] ([ExamPaperID], [QuestionID]) VALUES (1, 5)
INSERT [dbo].[ExamPaperQuestions] ([ExamPaperID], [QuestionID]) VALUES (1, 6)
INSERT [dbo].[ExamPaperQuestions] ([ExamPaperID], [QuestionID]) VALUES (1, 7)
INSERT [dbo].[ExamPaperQuestions] ([ExamPaperID], [QuestionID]) VALUES (1, 8)
INSERT [dbo].[ExamPaperQuestions] ([ExamPaperID], [QuestionID]) VALUES (1, 9)
INSERT [dbo].[ExamPaperQuestions] ([ExamPaperID], [QuestionID]) VALUES (1, 10)
GO
SET IDENTITY_INSERT [dbo].[ExamPapers] ON 

INSERT [dbo].[ExamPapers] ([ID], [Title], [Memo], [CreateTime]) VALUES (1, N'C#初级试题一（2021）', N'2021年10月生成', CAST(N'2021-12-13T22:26:44.0129362' AS DateTime2))
INSERT [dbo].[ExamPapers] ([ID], [Title], [Memo], [CreateTime]) VALUES (2, N'C#初级试题二（2021）', N'2021年11月生成', CAST(N'2021-12-13T22:26:44.0129382' AS DateTime2))
INSERT [dbo].[ExamPapers] ([ID], [Title], [Memo], [CreateTime]) VALUES (3, N'C#初级试题三（2021）', N'2021年12月生成', CAST(N'2021-12-13T22:26:44.0129383' AS DateTime2))
SET IDENTITY_INSERT [dbo].[ExamPapers] OFF
GO
SET IDENTITY_INSERT [dbo].[Questions] ON 

INSERT [dbo].[Questions] ([ID], [Question], [Score], [QuestionTypeID], [SujectTypeID]) VALUES (1, N'C#语言取消了（  ）语法。', 10, 1, 1)
INSERT [dbo].[Questions] ([ID], [Question], [Score], [QuestionTypeID], [SujectTypeID]) VALUES (2, N'以下类MyClass的属性count属于（ ）属性。
class MyClass
{
     int i;
     int count { get { return i; } }
}', 10, 1, 1)
INSERT [dbo].[Questions] ([ID], [Question], [Score], [QuestionTypeID], [SujectTypeID]) VALUES (3, N'（ ）语句只能在循环语句的循环体语句序列中使用。', 10, 1, 1)
INSERT [dbo].[Questions] ([ID], [Question], [Score], [QuestionTypeID], [SujectTypeID]) VALUES (4, N'在C#应用程序中，一般在程序的开头使用关键字（ ）来引入命名空间。', 10, 1, 1)
INSERT [dbo].[Questions] ([ID], [Question], [Score], [QuestionTypeID], [SujectTypeID]) VALUES (5, N'异常处理使用时，一般将可能出现异常的语句放在（ ）代码块中。', 10, 1, 1)
INSERT [dbo].[Questions] ([ID], [Question], [Score], [QuestionTypeID], [SujectTypeID]) VALUES (6, N'WinForms程序中，如果复选框控件的 Checked属性值设置为 True，表示（ ）。', 10, 1, 1)
INSERT [dbo].[Questions] ([ID], [Question], [Score], [QuestionTypeID], [SujectTypeID]) VALUES (7, N'在ADO.NET中，SqlConnection 类所在的命名空间是（ ）。', 10, 1, 1)
INSERT [dbo].[Questions] ([ID], [Question], [Score], [QuestionTypeID], [SujectTypeID]) VALUES (8, N'下面哪个类是用来以字节格式读写文件（ ）。', 10, 1, 1)
INSERT [dbo].[Questions] ([ID], [Question], [Score], [QuestionTypeID], [SujectTypeID]) VALUES (9, N'C#程序从上机到得到结果的几个操作步骤依次是( )。', 10, 1, 1)
INSERT [dbo].[Questions] ([ID], [Question], [Score], [QuestionTypeID], [SujectTypeID]) VALUES (10, N'下面的转换中不是隐式转换的是（ ）。', 10, 1, 1)
SET IDENTITY_INSERT [dbo].[Questions] OFF
GO
SET IDENTITY_INSERT [dbo].[QuestionTypes] ON 

INSERT [dbo].[QuestionTypes] ([ID], [TypeName]) VALUES (1, N'单项选择题')
INSERT [dbo].[QuestionTypes] ([ID], [TypeName]) VALUES (2, N'多项选择题')
INSERT [dbo].[QuestionTypes] ([ID], [TypeName]) VALUES (3, N'判断题')
SET IDENTITY_INSERT [dbo].[QuestionTypes] OFF
GO
SET IDENTITY_INSERT [dbo].[SubjectTypes] ON 

INSERT [dbo].[SubjectTypes] ([ID], [TypeName]) VALUES (1, N'C Sharp(C#)')
INSERT [dbo].[SubjectTypes] ([ID], [TypeName]) VALUES (2, N'SQL Server')
SET IDENTITY_INSERT [dbo].[SubjectTypes] OFF
GO
SET IDENTITY_INSERT [dbo].[UserExams] ON 

INSERT [dbo].[UserExams] ([ID], [UserID], [ExamPapgerID], [BeginTime], [EndTime]) VALUES (1, 1, 1, CAST(N'2021-12-01T00:00:00.000' AS DateTime), CAST(N'2022-12-01T00:00:00.000' AS DateTime))
SET IDENTITY_INSERT [dbo].[UserExams] OFF
GO
SET IDENTITY_INSERT [dbo].[Users] ON 

INSERT [dbo].[Users] ([ID], [UserName], [Password], [Salt], [Name], [Tel]) VALUES (1, N'zhangsan', N'@f232fd(feef', N'sfw32==', N'张三', N'13456879562')
INSERT [dbo].[Users] ([ID], [UserName], [Password], [Salt], [Name], [Tel]) VALUES (2, N'lisi', N'@22ewfd(feef', N'42syt==', N'李四', N'13456879562')

SET IDENTITY_INSERT [dbo].[Users] OFF
GO
ALTER TABLE [dbo].[ExamPapers] ADD  DEFAULT (getdate()) FOR [CreateTime]
GO
ALTER TABLE [dbo].[UserExamAnswers] ADD  DEFAULT (getdate()) FOR [CreateTime]
GO
ALTER TABLE [dbo].[Answers]  WITH CHECK ADD  CONSTRAINT [FK_Answers_Questions] FOREIGN KEY([QuestionID])
REFERENCES [dbo].[Questions] ([ID])
GO
ALTER TABLE [dbo].[Answers] CHECK CONSTRAINT [FK_Answers_Questions]
GO
ALTER TABLE [dbo].[ExamPaperQuestions]  WITH CHECK ADD  CONSTRAINT [FK_ExamPaperQuestions_ExamPapers] FOREIGN KEY([ExamPaperID])
REFERENCES [dbo].[ExamPapers] ([ID])
GO
ALTER TABLE [dbo].[ExamPaperQuestions] CHECK CONSTRAINT [FK_ExamPaperQuestions_ExamPapers]
GO
ALTER TABLE [dbo].[ExamPaperQuestions]  WITH CHECK ADD  CONSTRAINT [FK_ExamPaperQuestions_Questions] FOREIGN KEY([QuestionID])
REFERENCES [dbo].[Questions] ([ID])
GO
ALTER TABLE [dbo].[ExamPaperQuestions] CHECK CONSTRAINT [FK_ExamPaperQuestions_Questions]
GO
ALTER TABLE [dbo].[Questions]  WITH CHECK ADD  CONSTRAINT [FK_Questions_QuestionTypes] FOREIGN KEY([QuestionTypeID])
REFERENCES [dbo].[QuestionTypes] ([ID])
GO
ALTER TABLE [dbo].[Questions] CHECK CONSTRAINT [FK_Questions_QuestionTypes]
GO
ALTER TABLE [dbo].[Questions]  WITH CHECK ADD  CONSTRAINT [FK_Questions_SubjectTypes] FOREIGN KEY([SujectTypeID])
REFERENCES [dbo].[SubjectTypes] ([ID])
GO
ALTER TABLE [dbo].[Questions] CHECK CONSTRAINT [FK_Questions_SubjectTypes]
GO
ALTER TABLE [dbo].[UserExamAnswers]  WITH CHECK ADD  CONSTRAINT [FK_UserExamAnswers_Answers] FOREIGN KEY([AnswerID])
REFERENCES [dbo].[Answers] ([ID])
GO
ALTER TABLE [dbo].[UserExamAnswers] CHECK CONSTRAINT [FK_UserExamAnswers_Answers]
GO
ALTER TABLE [dbo].[UserExamAnswers]  WITH CHECK ADD  CONSTRAINT [FK_UserExamAnswers_UserExams] FOREIGN KEY([UserExamID])
REFERENCES [dbo].[UserExams] ([ID])
GO
ALTER TABLE [dbo].[UserExamAnswers] CHECK CONSTRAINT [FK_UserExamAnswers_UserExams]
GO
ALTER TABLE [dbo].[UserExams]  WITH CHECK ADD  CONSTRAINT [FK_UserExams_ExamPapers] FOREIGN KEY([ExamPapgerID])
REFERENCES [dbo].[ExamPapers] ([ID])
GO
ALTER TABLE [dbo].[UserExams] CHECK CONSTRAINT [FK_UserExams_ExamPapers]
GO
ALTER TABLE [dbo].[UserExams]  WITH CHECK ADD  CONSTRAINT [FK_UserExams_Users] FOREIGN KEY([UserID])
REFERENCES [dbo].[Users] ([ID])
GO
ALTER TABLE [dbo].[UserExams] CHECK CONSTRAINT [FK_UserExams_Users]
GO
```
データベースを構築した後、Mini APIプロジェクトにEntityFrameworkを導入しましょう。まず、dotnet-efツールをインストールします。
```shell
dotnet tool install --global dotnet-ef
```
次に、プロジェクトにnugetパッケージMicrosoft.EntityFrameworkCore.DesignとMicrosoft.EntityFrameworkCore.SqlServerを追加します。
これで、以下のコマンドを使用してデータベースからEFのエンティティクラスを生成することができます。
```shell
dotnet ef dbcontext scaffold "server=.;database=Exam;uid=sa;pwd=sa;" Microsoft.EntityFrameworkCore.SqlServer -o Models
```
![alt 画像](https://mmbiz.qpic.cn/mmbiz_png/4CAA63nvHRDPFLzroOSMyB2WibISMXdz1ia4BiaR5Pzz0Bke7GjIjjzB6YGgcBv2Faz5NlZ02BicSreZEKLrOVibdicQ/640?wx_fmt=png)

生成されたEFエンティティクラスを整理します。エンティティクラスをエクスポートする際に接続文字列が指定されているため、生成されたエンティティクラスにはこの接続文字列が含まれます。ExamContext.csを開いて、OnConfiguringメソッドを削除します。
![alt 画像](https://mmbiz.qpic.cn/mmbiz_png/4CAA63nvHRDPFLzroOSMyB2WibISMXdz1iaKmJauFGJ1tfAWT0s9Z29HPknQAPVhib7icl5woRtpqTcJcwqvgictxnQ/640?wx_fmt=png)

appsetings.jsonに接続文字列を設定します。
```json
"ConnectionStrings": {
  "ExamDatabase": "server=.;database=Exam;uid=sa;pwd=sa;"
}
```
次に、AddDbContextを使用してEFを導入します。Optionsパラメーターで、使用するデータベースの種類とデータベース接続文字列を指定します。その後、MapGetでサービスコンテナからExamContextを取得して使用します。
```csharp

using MiniDemo04.Models;
using Microsoft.EntityFrameworkCore;
using System.Text.Json.Serialization;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddDbContext<ExamContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("ExamDatabase")));

var app = builder.Build();

app.MapGet("/exampaper/{id}", async (ExamContext exam, int id) =>
 {
     return Results.Json(await exam.ExamPapers
     .Include(paper => paper.Questions)
     .ThenInclude(question => question.Answers)
     .Include(paper => paper.Questions)
     .ThenInclude(question => question.QuestionType)   
     .Select(paper => new { paper.Id, paper.Title, paper.CreateTime, Scores = paper.Questions.Sum(s => s.Score), Count = paper.Questions.Count, Questions = paper.Questions.Select(question => new { Question = $"{question.Id}、{question.Question1}({question.Score}分  {question.QuestionType.TypeName})", Answers = question.Answers.Select(answer => new { answer.Sequre, Answer = answer.Answer1 }) }) })
     .FirstOrDefaultAsync(s => s.Id == id), new System.Text.Json.JsonSerializerOptions { ReferenceHandler = ReferenceHandler.IgnoreCycles });
 });

app.Run();
```
実行結果：
![alt 画像](https://mmbiz.qpic.cn/mmbiz_png/4CAA63nvHRDPFLzroOSMyB2WibISMXdz1I4iaDm3Hq9eRCcPTSJ6mYJueSUtdKHj2n6zcWG8OZauXAOAysuM0rVw/640?wx_fmt=png)
(Translated by GPT)

元のリンク：https://mp.weixin.qq.com/s?__biz=MzA3NDM1MzIyMQ==&mid=2247484894&idx=1&sn=8252fbc9abd2b455e3f8f3af09d906f9&chksm=9f005af4a877d3e24f3738a07252ed52c1ec91275d6386b8760a2a045e776f14ced161fb7d0d&token=877361727&lang=zh_CN#rd