C#(C Sharp)使用 .NET 7、ASP.NET、Entity Framework、Postgres、Docker 和 Docker Compose 的 CRUD Rest API
让我们使用 C#(或 C sharp)创建一个 CRUD Rest API,使用:
- .NET 7
- ASP.NET(构建 Web 应用程序的框架)
- 实体框架(ORM)
- Postgres(数据库)
- Docker(容器化)
- Docker Compose(运行数据库和应用程序)
视频版本:
所有代码均可在 GitHub 存储库中找到(视频描述中的链接):https://youtube.com/live/PY6uD1fgzZA
🏁 简介
以下是我们要创建的应用程序架构图:
我们将为基本的 CRUD 操作创建 5 个端点:
- 创造
- 阅读全部
- 阅读一篇
- 更新
- 删除
以下是我们正在采取的步骤:
- 定义需求
- 创建新的 C# 项目
- 安装依赖项
- 配置数据库连接
- 创建 CRUD 操作的逻辑
- 更新项目
- Dockerfile
- docker-compose.yml
- 运行 Postgres 数据库和应用程序
- 更新数据库架构
- 测试应用程序
我们将提供一步一步的指南,以便您可以跟随。
📋 要求:
- .NET 7 已安装并正在运行
- dotnet CLI
- (可选):VS Code 的 C# 扩展包 ___ ## 🚀 创建一个新的 C# 项目
创建新的 C# 项目有很多方法,但我将使用 dotnet CLI
打开终端并运行以下命令:
dotnet new webapi -n csharp-crud-api
现在进入目录:
cd csharp-crud-api
📦安装依赖项
我们将使用以下依赖项:
- 实体框架
- Npgsql(Postgres 驱动程序)
要安装它们,请确保在csharp-crud-api
目录中并运行以下命令:
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
🔍 测试基础应用程序
在我们继续之前,让我们看看项目是否配置正确。
在 VS Code(或您最喜欢的 IDE)中打开该文件夹。
code .
您应该看到以下结构:
现在运行以下命令来启动应用程序:
dotnet run --urls=http://localhost:5000
您应该看到以下输出:
要测试应用程序,请打开浏览器并转到以下 URL:http://localhost:5000/weatherforecast
您应该看到以下输出:
现在是时候开始编写应用程序代码了。
📝 编写应用程序代码
编写应用程序有三个步骤:
- 配置数据库连接
- 创建 CRUD 操作的逻辑
- 更新
Program.cs
文件
🗄️配置数据库连接
打开appsettings.json
文件并添加以下行:
{
"ConnectionStrings": {
"DefaultConnection": "Host=db;Port=5432;Database=postgres;Username=postgres;Password=postgres"
}
}
您的appsettings.json
文件应如下所示:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "Host=db;Port=5432;Database=postgres;Username=postgres;Password=postgres"
}
}
✏️ 创建 CRUD 操作的逻辑
创建一个名为 的新文件夹,并在其中Models
创建一个名为 的新文件。User.cs
填充User.cs
以下代码:
using System.ComponentModel.DataAnnotations.Schema;
namespace Models
{
[Table("users")]
public class User
{
[Column("id")]
public int Id { get; set; }
[Column("name")]
public string Name { get; set; }
[Column("email")]
public string Email { get; set; }
}
}
现在创建一个名为 的新文件夹,并在其中Data
创建一个名为 的新文件。UserContext.cs
UserContext.cs
使用以下代码填充文件:
using Models;
using Microsoft.EntityFrameworkCore;
namespace Data
{
public class UserContext : DbContext
{
public UserContext(DbContextOptions<UserContext> options) : base(options)
{
}
public DbSet<User> Users { get; set; }
}
}
现在创建一个名为 的新文件夹,并在其中Controllers
创建一个名为 的新文件。UsersController.cs
UserscController.cs
使用以下代码填充文件:
using Data;
using Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace csharp_crud_api.Controllers;
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
private readonly UserContext _context;
public UsersController(UserContext context)
{
_context = context;
}
// GET: api/users
[HttpGet]
public async Task<ActionResult<IEnumerable<User>>> GetUsers()
{
return await _context.Users.ToListAsync();
}
// GET: api/users/5
[HttpGet("{id}")]
public async Task<ActionResult<User>> GetUser(int id)
{
var user = await _context.Users.FindAsync(id);
if (user == null)
{
return NotFound();
}
return user;
}
// POST: api/users
[HttpPost]
public async Task<ActionResult<User>> PostUser(User user)
{
_context.Users.Add(user);
await _context.SaveChangesAsync();
return CreatedAtAction(nameof(GetUser), new { id = user.Id }, user);
}
// PUT: api/users/5
[HttpPut("{id}")]
public async Task<IActionResult> PutUser(int id, User user)
{
if (id != user.Id)
{
return BadRequest();
}
_context.Entry(user).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!UserExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
// DELETE: api/users/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteUser(int id)
{
var user = await _context.Users.FindAsync(id);
if (user == null)
{
return NotFound();
}
_context.Users.Remove(user);
await _context.SaveChangesAsync();
return NoContent();
}
private bool UserExists(int id)
{
return _context.Users.Any(e => e.Id == id);
}
// dummy method to test the connection
[HttpGet("hello")]
public string Test()
{
return "Hello World!";
}
}
🖋️ 更新Program.cs
文件
我们快完成了,现在我们只需要更新Program.cs
文件。
在文件顶部添加这两个导入:
using Data;
using Microsoft.EntityFrameworkCore;
并且这些行位于var app = builder.Build();
行上方:
// Added configuration for PostgreSQL
var configuration = builder.Configuration;
builder.Services.AddDbContext<UserContext>(options =>
options.UseNpgsql(configuration.GetConnectionString("DefaultConnection")));
Program.cs
或者您可以用以下代码替换整个文件:
using Data;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Added configuration for PostgreSQL
var configuration = builder.Configuration;
builder.Services.AddDbContext<UserContext>(options =>
options.UseNpgsql(configuration.GetConnectionString("DefaultConnection")));
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
我们已经完成了应用程序逻辑,现在是时候对其进行 Docker 化了。
🐳 Docker 化应用程序
我们将通过创建和填充两个文件来 Docker 化该应用程序:
- Dockerfile
- docker-compose.yml
🐋 Dockerfile
在项目的根目录下创建一个名为的新文件Dockerfile
,并用以下代码填充它:
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /app
COPY *.csproj ./
RUN dotnet restore
COPY . ./
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS runtime
WORKDIR /app
COPY --from=build /app/out ./
ENTRYPOINT ["dotnet", "csharp-crud-api.dll"]
解释:
Dockerfile 中有两个阶段,build
和runtime
。
构建阶段:
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
:此行告诉 Docker 使用该mcr.microsoft.com/dotnet/sdk:7.0
映像作为构建阶段的基础映像。WORKDIR /app
:此行告诉 Docker 将工作目录设置为/app
。COPY *.csproj ./
:此行告诉 Docker 将所有.csproj
文件复制到工作目录。RUN dotnet restore
:此行告诉 Docker 运行dotnet restore
命令。COPY . ./
:此行告诉 Docker 将所有文件复制到工作目录。RUN dotnet publish -c Release -o out
:此行告诉 Docker 运行dotnet publish
命令。
运行时阶段:
此阶段与构建阶段非常相似,唯一的区别是我们使用mcr.microsoft.com/dotnet/aspnet:7.0
图像作为基础图像。
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS runtime
:此行告诉 Docker 使用该mcr.microsoft.com/dotnet/aspnet:7.0
映像作为运行时阶段的基础映像。WORKDIR /app
:此行告诉 Docker 将工作目录设置为/app
。COPY --from=build /app/out ./
:此行告诉 Docker 将out
文件夹从构建阶段复制到工作目录。ENTRYPOINT ["dotnet", "csharp-crud-api.dll"]
:此行告诉 Docker 运行dotnet csharp-crud-api.dll
命令。
🐙 docker-compose.yml
在项目的根目录下创建一个名为的新文件docker-compose.yml
,并用以下代码填充它:
version: '3'
services:
csharp_app:
container_name: csharp_app
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:80"
depends_on:
- db
environment:
ConnectionStrings__DefaultConnection: "Host=db;Database=postgres;Username=postgres;Password=postgres"
db:
container_name: db
image: postgres:12
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=postgres
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata: {}
解释:
解释:
- 我们定义了两个服务:
csharp_app
和db
.Csharp_app: container_name: csharp_app
:这一行告诉 Docker 命名容器csharp_app
。build:
:此行告诉 Docker 从 构建映像Dockerfile
。ports:
8080
:这一行告诉Docker将容器的端口暴露给80
主机的端口。depends_on:
:这一行告诉Docker该csharp_app
容器依赖于该db
容器。environment:
:此行告诉 Docker 为设置环境变量ConnectionStrings__DefaultConnection
。
数据库:
container_name: db
:这一行告诉 Docker 命名容器db
。image: postgres:12
:此行告诉 Docker 使用该postgres:12
图像作为容器的基础图像。environment:
POSTGRES_USER
:此行告诉 Docker 为、POSTGRES_PASSWORD
和设定环境变量POSTGRES_DB
。ports:
5432
:这一行告诉Docker将容器的端口暴露给5432
主机的端口。volumes:
:此行告诉 Docker 将pgdata
卷挂载到/var/lib/postgresql/data
容器的目录中。
我们还需要定义容器pgdata
使用的体积db
。
大功告成!现在我们可以运行 Postgres 和应用程序容器了。
🏃♂️ 运行应用程序
我们将运行文件中定义的容器(服务)docker-compose.yml
。
🐘 运行 Postgres 容器
docker compose up -d db
📜 在数据库中创建表
我们可以用不同的方式创建表,但让我向您展示如何直接从应用程序容器中执行此操作。
首先,确保 Postgres 容器正在运行。
打开不同的终端并运行以下命令:
docker exec -it db psql -U postgres
现在我们已经进入了 Postgres 容器。我们可以使用以下命令创建表:
CREATE TABLE "users" (
"id" SERIAL PRIMARY KEY,
"name" VARCHAR(50) NOT NULL,
"email" VARCHAR(255) NOT NULL
);
🏗️ 构建并运行应用程序容器
构建 Docker 镜像:
docker compose build
运行应用程序容器:
docker compose up csharp_app
🧪 测试应用程序
让我们用 Postman 测试应用程序
现在我们可以测试项目了。我们将使用 Postman,但您也可以使用任何其他工具。
📝 创建用户
要创建新用户,请创建一个POST request to localhost:8080/api/users
。
请求主体应该是这样的:
{
"name": "aaa",
"email": "aaa@mail"
}
输出应该是这样的:
让我们再创建两个用户,创建一个POST request to localhost:8080/api/users
。
{
"name": "bbb",
"email": "bbb@mail"
}
{
"name": "ccc",
"email": "ccc@mail"
}
📝 获取所有用户
要获取所有用户,请创建一个GET request to localhost:8000/api/users
。
输出应该是这样的:
📝 获取用户
要获得用户,请创建一个GET request to localhost:8000/api/users/{id}
。
例如GET request to localhost:8000/api/users/1
。
输出应该是这样的:
📝 更新用户
要更新用户,请制作PUT request to localhost:8000/api/users/{id}
。
例如PUT request to localhost:8000/api/users/2
。
请求主体应该是这样的:
{
"name": "Francesco",
"email": "francesco@mail"
}
输出应该是这样的:
📝 删除用户
要删除用户,请创建一个DELETE request to localhost:8000/api/users/{id}
。
例如DELETE request to localhost:8000/api/users/1
。
在 Postman 上你应该会看到类似这样的内容:
最终测试
作为最后的测试,我们可以使用 TablePlus 检查数据库。
🏁结论
我们成功了!我们用 C#(或 C sharp)构建了一个 CRUD Rest API 项目,使用:
- .NET 7
- ASP.NET(构建 Web 应用程序的框架)
- 实体框架(ORM)
- Postgres(数据库)
- Docker(容器化)
- Docker Compose(运行数据库和应用程序)
视频版本:
所有代码均可在 GitHub 存储库中找到(视频描述中的链接):https://youtube.com/live/PY6uD1fgzZA
就这样。
如果您有任何疑问,请在下面发表评论。
文章来源:https://dev.to/francescoxx/cc-sharp-crud-rest-api-using-net-7-aspnet-entity-framework-postgres-docker-and-docker-compose-493a