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 后端开发教程 - Java、Spring Boot 实战 - msg200.com
            后端开发教程 - Java、Spring Boot 实战 - msg200.com
          









