在本文中,我们将使用Entity Framework Core(EF Core)实现一个.NET 7 Web API CRUD示例。
Web API是一个构建HTTP服务的框架,可以从浏览器、移动设备和桌面应用等任何客户端访问这些服务。
简单来说,API(应用程序编程接口)是指包含编程函数的接口模块,可以通过HTTP调用请求这些函数,为各自的客户端获取或更新数据。
API的一些关键特征:
- 支持HTTP不同请求方式,如“GET”,“POST”,“PUT”,“DELETE”等。
- 支持默认响应,如'XML'和'JSON'。还可以定义自定义响应。
- 支持自托管或个人托管,以便所有不同类型的应用程序都可以使用它。
- 易于实现验证和授权。
- 构建REST完整服务的理想平台。
安装SQL Server和SQL Management Studio:
让我们在本地机器上安装SQL server。因此,请访问` microsoft.com/en/sql-server/sql-server-downloads `,下载` Developer `版本,然后继续安装。
现在在` https://learn.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver16 `上安装SSMS(SQL Server Management Studio) IDE
创建一个示例数据库:
运行下面的脚本来创建一个示例数据库。
CREATE DATABASE MyWorldDB
- 这里'MyWorldDB'是我们数据库的名称。
创建一个示例表:
让我们运行以下SQL脚本来创建` Students `的新表。当运行下面的脚本时,请确保选择您的活动数据库,我们必须在其下创建对应的表。
CREATE TABLE Students (
Id INT IDENTITY(1,1) NOT NULL,
FirstName VARCHAR(200) NULL,
LastName VARCHAR(100) NULL,
Age INT,
Gender VARCHAR(10) NULL
CONSTRAINT PK_Students PRIMARY KEY (Id)
)
- 'Students'是我们表的名字,这里我们有像'Id', 'FirstName', 'LastName', 'Age'和'Gender'这样的列。'Id'列是表的主键列。
安装.NET 7 SDK:
注意:安装.net 7 SDK仅适用于.net CLI用户。Visual Studio用户应该有Visual Studio 2022(v17.4)来与. net 7应用程序一起工作,它将自动安装. net 7 SDK。
. net CLI用户必须安装.net 7 SDK,所以请访问` https://dotnet.microsoft.com/en-us/download/dotnet/7.0 `,然后下载安装到本地机器上。
创建.net 7 Web API应用程序:
让我们创建一个.net 7 Web API示例应用程序来完成我们的演示。我们可以使用Visual Studio 2022或Visual Studio Code(使用. net CLI命令)来创建任何.net 7应用程序。在这个演示中,我使用的是` Visual Studio Code `编辑器。
dotnet new webapi -o name_of_your_project
现在运行下面的命令,使用. net CLI启动我们的应用程序。
dotnet watch run --launch-profile https
在我们的API项目中,` Program.cs `文件是入口文件。所以让我们来看看` Program.cs `文件中配置的默认服务和中间件。
'Program.cs'中的服务配置:
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
- (行:1) API控制器的` AddControllers `服务。
- (行: 2) ` AddEndpointAPIExplorer `服务提供了对最小API的支持。
- (行: 3) ` AddSwagerGen `添加swagger服务支持。
'Program.cs'中的中间件:
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
- (行: 3&4) Swagger中间件用来加载Swagger页面。
- (行: 6) ` UseHttpsRedirection `中间件将` HTTP `请求重定向到` HTTPs `。
- (行: 7) 用户授权、认证中间件。
- (行: 8) ` MapControllers `是一个端点中间件,它可以指向API控制器的路由。
SQL数据库连接字符串:
让我们准备SQL连接字符串。
SQL连接字符串示例:
Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=MyWorldDB;Integrated Security=True;Connect Timeout=30
- Data Source - SQL服务器名称。
- Initial Catalog -数据库名称
- Integrated Security -indows认证。
- Connect Time - 连接超时时间。
Entity Framework Core:
Entity Framework Core 是一个对象/关系映射(ORM)框架。EF Core使数据库通信更加流畅和简单。` DatabaseContext `类在我们的c#代码中充当数据库,它将包含所有注册的类` DbSet<TEntity> ` (TEntity是任何表示表的POCO类)。
安装Entity Framework Core NuGet包:
//使用vs包管理器
Install-Package Microsoft.EntityFrameworkCore -Version 7.0.0
//使用控制台命令
dotnet add package Microsoft.EntityFrameworkCore --version 7.0.0
让我们安装 Entity Frame Core SQLServer 包
vs 包管理器命令
Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 7.0.0
命令行命令
dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 7.0.0
设置Entity Framework Core DatabaseContext:
现在添加一个新类来表示我们的` Students `表。因此,让我们创建一个新文件夹,如` Data/Entities `,然后添加新类,如` Students.cs `。
Data/Entities/Students.cs:
namespace dot7.API.Crud.Data.Entities;
public class Students
{
public int Id { get; set; }
public string? FirstName { get; set; }
public string? LastName { get; set; }
public int? Age {get;set;}
public string? Gender{get;set;}
}
- 这里有一些属性类型后有` ?`,表示这些属性是可空的,代表表中的可空列。
为了管理或控制c#中所有的表类,我们必须创建DatabaseContext类。因此,让我们在` Data `文件夹中创建我们的context类,如` MyWorldDbContext.cs `。
Data/MyWorldDbContext.cs:
using dot7.API.Crud.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace dot7.API.Crud.Data;
public class MyWorldDbContext : DbContext
{
public MyWorldDbContext(DbContextOptions<MyWorldDbContext> context) : base(context)
{
}
public DbSet<Students> Students { get; set; }
}
- (行: 6)MyWorldDbContent 继承自 'Microsoft.EntityFramework.DbContext' ,是用于访问数据库上下文类。
- (行: 8) 'Microsoft.EntityFrameworkCore.DbContextOptions'是一个选项的实例,我们将在` Program.cs `中注册它,就像` ConnectionString `、` DatabaseProvider `等。
- (行: 13) 我们所有的表类必须在数据库上下文类中使用` DbSet<T> `注册,以便Entity Framework Core可以与数据库的表通信。
在` appsettings.Development. json `文件中,添加数据库连接字符串。
appsettings.Development.json:
"ConnectionStrings": {
"MyWorldDbConnection":""
}
在` Program.cs `的应用程序依赖注入服务中注册数据库上下文
Program.cs:
builder.Services.AddDbContext<MyWorldDbContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("MyWorldDbConnection"));
});
- 这里传递连接字符串属性。
创建一个'Students' API控制器:
在Web api中,控制器是HTTP请求的入口点。“Action”方法是控制器中的逻辑单元,它被执行并向请求的客户端返回响应。
现在在` Controllers `文件夹中创建一个示例API控制器,例如` StudentsController `。
Controllers/StudentsController.cs:
using dot7.API.Crud.Data;
using Microsoft.AspNetCore.Mvc;
namespace dot7.API.Crud.Controllers;
[ApiController]
[Route("[controller]")]
public class StudentsController: ControllerBase
{
private readonly MyWorldDbContext _myWorldDbContext;
public StudentsController(MyWorldDbContext myWorldDbContext)
{
_myWorldDbContext = myWorldDbContext;
}
}
- (行: 6) 用` ApiController `装饰器。它向控制器提供API特性,如果我们不使用装饰器,API版本控制之类的功能将不起作用。因此,为控制器配置装饰器是必要的。
- (行: 7) Route属性定义API的URL。默认表达式` [Controller] `意味着URL将包含控制器名称(例如:` Students `将在路由地址中)。我们也可以定义与控制器名称不同的自定义路由。
- (行: 8) 为了让我们的` StudentsController `类成为一个API控制器,它必须继承` Microsoft.AspNetCore.Mvc.ControllerBase `。
- (行: 10-14) 将我们的` DatabaseContext ` (MyWorldDbContext)注入到我们的控制器构造函数中。
读(R)操作:
让我们为HTTP GET请求创建一个动作方法(这是控制器的一个逻辑单元)。在这个action方法中,我们必须实现从数据库中获取所有数据的逻辑。
Controllers/StudentsController.cs:
using Microsoft.EntityFrameworkCore;
[HttpGet]
public async Task<IActionResult> GetAsync()
{
var students = await _myWorldDbContext.Students.ToListAsync();
return Ok(students);
}
- 在这里,我们可以观察到操作方法上没有` Route[] `属性。如果我们的控制器包含一个HTTP GET动作方法,那么添加` Route[] `属性是可选的。按照约定,API将基于每个请求可用的HTTP动词头执行操作方法。但是如果我们有多个HTTP动词类型的操作方法,如` GET `、` POST `、` PUT `和` Delete `,那么我们必须为每个操作方法明确定义路由。
- (行: 3) ` HttpGet `属性表示我们的action方法在HTTP GET请求中被调用。
- (行: 4-8) 定义了一个异步操作方法来返回数据集合。
- (行: 6) 异步调用从` Students `实体中获取所有记录。` ToListAsync `是` Microsoft.EntityFrameworkCor `提供的扩展。
- (行: 7) ` Ok() `方法创建一个OkObjectResult,它会生成一个StatuCodes.Status200Ok(表示200成功)响应。
为了测试这个端点,让我们插入一些数据到我们的` Students `表中,如下所示。
现在运行应用程序并使用swagger页面(这是用于测试API端点的开发人员页面)测试我们的HTTP GET端点
(步骤1):
(步骤2)
现在在我们的编辑器终端中,我们可以观察实体框架如何记录它如何创建用于获取数据的SQL查询。
创建(C)操作:
让我们为HTTP POST请求创建一个动作方法(这是控制器的逻辑单元)。在这个操作方法中,我们必须实现将新记录保存到数据库中的逻辑。
Controllers/StudentsController.cs:
[HttpGet]
[Route("get-student-by-id")]
public async Task<IActionResult> GetStudentByIdAsync(int id)
{
var student = await _myWorldDbContext.Students.FindAsync(id);
return Ok(student);
}
[HttpPost]
public async Task<IActionResult> PostAsync(Students student)
{
_myWorldDbContext.Students.Add(student);
await _myWorldDbContext.SaveChangesAsync();
return Created(#34;/get-student-by-id?id={student.Id}", student);
}
- (行: 9) ` HttpPost `属性代表了我们的action方法,该方法只在HTTP POST请求时执行。
- (行: 10-15) 异步操作方法,用于在数据库中创建新记录。
- (行: 12) 数据库上下文中的` Add `方法开始跟踪给定的新项目。这将更新数据库上下文的状态为` EntityState `。这意味着数据已经准备好保存到数据库中。
- (行: 13) ` SaveChangesAsync() `方法将我们的数据保存到数据库中。
- (行: 14) ` Created() `方法创建一个CreatedResult对象,该对象产生201状态码(已创建状态码)作为响应。` Created() `方法的第一个参数将是端点的URL,我们可以在这里获取新创建的项目,因此为了生成URL,我们创建了另一个HTTP get操作方法(第1-7行),通过` Id `获取数据,在这里我们添加了第二个HTTP get端点,因此我们显式添加了路由。如果你愿意,你也可以使用` Ok() `方法作为HTTP POST操作方法的返回类型。
(步骤1)
(步骤2) 让我们使用HTTP POST端点创建一个新的学生记录
(步骤3)
现在我们可以观察实体框架核心是如何生成插入查询的。
(步骤4)
现在通过` id `端点访问student来检查新创建的项目。
(步骤 5) 现在观察Entity Framework如何根据学生的` id `值生成where条件的SQL查询。
更新(U)操作:
让我们为HTTP PUT请求创建一个Action方法(这是控制器的一个逻辑单元)。在这个操作方法中,我们必须实现更新数据库中项目数据的逻辑。
Controllers/StudentsController.cs:
[HttpPut]
public async Task<IActionResult> PutAsync(Students studentToUpdate)
{
_myWorldDbContext.Students.Update(studentToUpdate);
await _myWorldDbContext.SaveChangesAsync();
return NoContent();
}
- (行: 1)` HttpPut `代表了我们的action方法,只在HTTP PUT请求时执行。
- (行: 2-7) 更新记录的异步方法。
- (行: 4) ` Update() `方法将数据库上下文状态更改为` Entity. js `。Modified'表示数据被读取来更新。` Update() `方法将更新已记录的所有列,因此请确保这是否是完整更新的情况。如果你尝试只传递几列数据,那么其余的列将更新它们的默认值。还有一件事要记住,对象应该包含` Id `(主键)和value。
- (Line: 5) ` SaveChangesAsync() `方法更新数据库中的数据。
- (Line: 6) ` NoContent() `方法创建一个` NoContentResult `对象,该对象生成一个状态码为204的空值作为响应。
现在测试我们的HTTP PUT端点。
(步骤 1)
(步骤 2)
(步骤 3)
(步骤 4)现在我们可以观察Entity Framework是如何生成SQL更新查询的
删除(D)操作:
让我们为HTTP DELETE请求创建一个动作方法(这是控制器的一个逻辑单元)。在这个action方法中,我们必须实现从数据库中删除项的逻辑。
Controllers/StudentsController.cs:
[Route("{id}")]
[HttpDelete]
public async Task<IActionResult> DeleteAsync(int id)
{
var studentToDelete = await _myWorldDbContext.Students.FindAsync(id);
if (studentToDelete == null)
{
return NotFound();
}
_myWorldDbContext.Students.Remove(studentToDelete);
await _myWorldDbContext.SaveChangesAsync();
return NoContent();
}
- (行: 1) ` [Route] `属性的定义意味着` id `(我们必须删除的项目id)的值应该作为URL的一部分传递,而`{}`表达式意味着在它内部定义的任何字符串都将成为操作方法的输入参数。
- (行: 2) ` HttpDelete `属性表示我们的action方法只在HTTP DELETE请求时被调用。
- (行: 3-13) 从数据库中删除记录的异步操作方法。
- (行: 5)从数据库中获取需要删除的记录。
- (行: 6-9)正在验证要删除的记录。如果数据库中没有有效记录,那么我们返回` NotFound() `方法的状态码为` 404 `。
- (行: 10-11) 从数据库上下文中删除记录。` SaveChangesAsync() `更新数据库上下文以删除记录。
- (行: 12) ` NoContent() `的状态码是` 204 `。
让我们测试一下HTTP DELETE端点。
(步骤1)
(步骤2)
(步骤3)
总结:
希望本文能提供一些关于。net 7 Web API CRUD操作的有用信息。我喜欢在下面的评论部分得到你的反馈、建议和更好的技术。
本文暂时没有评论,来添加一个吧(●'◡'●)