Bài tập - Thêm EF Core vào API tối thiểu

Đã hoàn thành

Bạn là nhà phát triển cho một công ty và bạn và công ty của bạn đã nghe nói về API tối thiểu mới. Người quản lý của bạn đã yêu cầu bạn tạo dự án cho dự án đó để bạn có thể thảo luận xem có nên sử dụng dự án đó trong dự án tiếp theo của mình hay không.

Ghi

Mô-đun này sử dụng .NET CLI (Command Line Interface) và Visual Studio Code để phát triển cục bộ. Sau khi hoàn thành mô-đun này, bạn có thể áp dụng các khái niệm bằng visual Studio (Windows), Visual Studio for Mac (macOS) hoặc tiếp tục phát triển bằng Visual Studio Code (Windows, Linux, & macOS).

Mô-đun này sử dụng .NET 8.0 SDK. Đảm bảo rằng bạn đã cài đặt .NET 8.0 bằng cách chạy lệnh sau đây trong thiết bị đầu cuối lệnh yêu thích của bạn:

dotnet --list-sdks

Đầu ra tương tự như ví dụ sau đây xuất hiện:

6.0.317 [C:\Program Files\dotnet\sdk]
7.0.401 [C:\Program Files\dotnet\sdk]
8.0.100 [C:\Program Files\dotnet\sdk]

Hãy đảm bảo rằng phiên bản bắt đầu bằng 8 được liệt kê. Nếu không có mục nào được liệt kê hoặc không tìm thấy lệnh, đặt phiên bản .NET 8.0 SDK mới nhất.

Thiết lập dự án

Trước tiên, bạn cần tạo dự án. Bạn đã cài đặt .NET 6 và đã sẵn sàng sử dụng. Trong đơn vị này, bạn sẽ thêm tính bền vững dữ liệu vào API quản lý pizza.

  1. Trong một thiết bị đầu cuối, tạo một API web bằng cách chạy dotnet new:

    dotnet new web -o PizzaStore -f net8.0
    

    Bạn sẽ thấy danh bạ PizzaStore này.

  2. Đi tới thư cửa hàng PizzaStore bằng cách nhập lệnh sau:

    cd PizzaStore
    
  3. Cài đặt gói Swashbuckle:

    dotnet add package Swashbuckle.AspNetCore --version 6.5.0
    
  4. Mở dự án trong Mã Visual Studio.

  5. Sử dụng Mã Visual Studio, tạo tệp Pizza.cs trong gốc dự án và cung cấp nội dung sau:

    namespace PizzaStore.Models 
    {
        public class Pizza
        {
              public int Id { get; set; }
              public string? Name { get; set; }
              public string? Description { get; set; }
        }
    }
    

    Lớp sản Pizza trước là một đối tượng đơn giản đại diện cho một bánh pizza. Mã này là mô hình dữ liệu của bạn. Sau đó, bạn sẽ sử dụng Entity Framework (EF) Core để ánh xạ mô hình dữ liệu này đến bảng cơ sở dữ liệu.

  6. Mở Program.cs và thêm mã được tô sáng:

    using Microsoft.OpenApi.Models;
    
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen(c =>
    {
         c.SwaggerDoc("v1", new OpenApiInfo {
             Title = "PizzaStore API",
             Description = "Making the Pizzas you love",
             Version = "v1" });
    });
    
    var app = builder.Build();
    if (app.Environment.IsDevelopment())
    {
       app.UseSwagger();
       app.UseSwaggerUI(c =>
       {
          c.SwaggerEndpoint("/swagger/v1/swagger.json", "PizzaStore API V1");
       });
    }
    
    app.MapGet("/", () => "Hello World!");
    
    app.Run();
    

    Bạn có thể nhận được lời nhắc từ Mã Visual Studio để thêm tài nguyên để gỡ lỗi dự án. Chọn Yes trong hộp thoại.

Thêm EF Core vào dự án

Để lưu trữ các mục trong danh to-do, hãy cài đặt gói EntityFrameworkCore.InMemory này.

  1. Nhấn Ctrl+' mở một thiết bị đầu cuối trong Visual Studio Code. Trong thiết bị đầu cuối mới, nhập mã sau để thêm gói EF Core InMemory:

    dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 8.0
    
  2. Thêm using Microsoft.EntityFrameworkCore; vào đầu tài liệu và Program.cs tệp Pizza.cs bạn.

    Bây giờ bạn đã thêm EF Core vào dự án, bạn có thể chuyển mã của bạn lên đến dữ liệu bạn muốn lưu và truy vấn nó. Để thực hiện bước này, bạn tạo lớp PizzaDb khác. Lớp PizzaDb sẽ thực hiện các tác vụ sau:

    • Hiển thị thuộc Pizzas dữ liệu của bạn từ danh sách Pizza dữ liệu trong cơ sở dữ liệu.
    • Sử dụng UseInMemoryDatabase để chuyển dây lưu trữ cơ sở dữ liệu trong bộ nhớ. Dữ liệu của bạn được lưu trữ ở đây miễn là ứng dụng đang chạy.
  3. Để thiết lập cơ sở dữ liệu trong bộ nhớ, hãy thêm mã sau đây vào cuối tệp Pizza.cs (phía trên tệp cuối cùng }). Bạn sẽ có hai định nghĩa lớp trong không gian PizzaStore.Models tên.

    class PizzaDb : DbContext
    {
        public PizzaDb(DbContextOptions options) : base(options) { }
        public DbSet<Pizza> Pizzas { get; set; } = null!;
    }
    

    DbContext thể hiện kết nối hoặc phiên được sử dụng để truy vấn và lưu phiên bản thực thể trong cơ sở dữ liệu.

  4. Thêm using PizzaStore.Models; vào đầu tệp tin Program.cs bạn.

  5. Trong Program.cs, trước khi cuộc gọi AddSwaggerGen, hãy thêm mã sau đây:

    builder.Services.AddDbContext<PizzaDb>(options => options.UseInMemoryDatabase("items"));
    

Trả về danh sách các mục

  • Để đọc từ danh sách các mặt hàng trong danh sách pizza, hãy thêm mã sau đây ở phía trên cuộc gọi đến app.Run(); để thêm tuyến đường "/pizzas":

    app.MapGet("/pizzas", async (PizzaDb db) => await db.Pizzas.ToListAsync());
    

Chạy ứng dụng

  1. Đảm bảo rằng bạn đã lưu tất cả thay đổi của mình. Chạy ứng dụng bằng cách gọi dotnet run thiết bị đầu cuối. Hành động này sẽ xây dựng ứng dụng và lưu trữ ứng dụng trên một cổng từ 5000-5300. HTTPS sẽ có một cổng được chọn cho cổng đó trong phạm vi 7000-7300.

    Ghi

    Nếu bạn muốn ghi đè hành vi lựa chọn cổng ngẫu nhiên, bạn có thể thiết lập các cổng để sử dụng trong launchSettings.json.

    dotnet run
    

    Đây là những gì đầu ra có thể trông giống như trong thiết bị đầu cuối:

    Building...
     info: Microsoft.Hosting.Lifetime[14]
           Now listening on: https://localhost:7200
     info: Microsoft.Hosting.Lifetime[14]
           Now listening on: http://localhost:5100
     info: Microsoft.Hosting.Lifetime[0]
           Application started. Press Ctrl+C to shut down.
     info: Microsoft.Hosting.Lifetime[0]
           Hosting environment: Development
     info: Microsoft.Hosting.Lifetime[0]
           Content root path: /<path>/PizzaStore
    
  2. Trong trình duyệt của bạn, đi tới https://localhost:{PORT}/swagger. Chọn nút GET /pizzas, tiếp theo là thử và thực thực. Bạn sẽ thấy danh sách trống trong Response body.

  3. Trong thiết bị đầu cuối, Ctrl+C để chạy chương trình.

Tạo mục mới

Hãy thêm mã vào danh sách POST hàng mới vào danh sách pizza. Trong Program.cs, hãy thêm mã sau đây vào phần app.MapGet bạn đã tạo trước đó.

app.MapPost("/pizza", async (PizzaDb db, Pizza pizza) =>
{
    await db.Pizzas.AddAsync(pizza);
    await db.SaveChangesAsync();
    return Results.Created($"/pizza/{pizza.Id}", pizza);
});

Kiểm tra API

Đảm bảo rằng bạn đã lưu tất cả thay đổi của mình và chạy lại ứng dụng. Quay lại giao diện người dùng Swagger và bây giờ bạn sẽ thấy giao POST/pizza. Để thêm các mặt hàng mới vào danh sách pizza:

  1. Chọn POST /pizza.

  2. Chọn thử tính năng.

  3. Thay thế nội dung yêu cầu bằng JSON sau:

    {
        "name": "Pepperoni",
        "description": "A classic pepperoni pizza"
    }
    
  4. Chọn thực.

Để đọc các mục trong danh sách:

  1. Chọn tải /pizza.

  2. Chọn thử tính năng.

  3. Chọn thực.

    Các Response body sẽ bao gồm các mục vừa được thêm vào.

    [
      {
        "id": 1,
        "name": "Pepperoni",
        "description": "A classic pepperoni pizza"
      }
    ]
    
  4. Nhấn Ctrl+C thiết bị đầu cuối để ngừng chạy ứng dụng. Đối với phần còn lại của bài tập này, dừng và khởi động lại ứng dụng như mong muốn để kiểm tra các thay đổi của bạn. Hãy nhớ lưu tất cả các thay đổi của bạn trước khi dotnet run!

Nhận một mục duy nhất

Để NHẬN một mục bằng cách id, hãy thêm mã trong định tuyến app.MapPost bạn đã tạo trước đó.

app.MapGet("/pizza/{id}", async (PizzaDb db, int id) => await db.Pizzas.FindAsync(id));

Kiểm tra GET by ID

Để kiểm tra thao tác này, bạn có thể đi https://localhost:{PORT}/pizza/1 sử dụng giao diện người dùng Swagger. Vì bạn đang sử dụng cơ sở dữ liệu trong bộ nhớ, bánh pizza mà bạn đã tạo trước đó sẽ không được liệt kê nếu bạn đã khởi động lại ứng dụng. Vì vậy, bạn sẽ cần sử dụng thao tác POST của mình để thêm lại thao tác này.

Cập nhật một mục

Để cập nhật mục hiện có, hãy thêm mã dưới tuyến GET /pizza/{id} bạn đã tạo:

app.MapPut("/pizza/{id}", async (PizzaDb db, Pizza updatepizza, int id) =>
{
      var pizza = await db.Pizzas.FindAsync(id);
      if (pizza is null) return Results.NotFound();
      pizza.Name = updatepizza.Name;
      pizza.Description = updatepizza.Description;
      await db.SaveChangesAsync();
      return Results.NoContent();
});

Kiểm thử PUT

  1. Chọn đặt /pizza/{id} giao diện người dùng Swagger.

  2. Chọn thử tính năng.

  3. Trong hộp id, hãy nhập 1 1.

  4. Cuối cùng, cập nhật Request body. Dán JSON sau đây và thay đổi name thành Pineapple.

    {
       "id": 1,
       "name": "Pineapple"
    }
    
  5. Chọn thực.

Để kiểm tra mã, hãy cuộn trở lại GET /pizza/{id}. Pizza bây giờ có tên là Pineapple.

Xóa một mục

Để xóa mục hiện có, hãy thêm mã bên dưới PUT /pizza/{id} bạn đã tạo trước đó:

app.MapDelete("/pizza/{id}", async (PizzaDb db, int id) =>
{
   var pizza = await db.Pizzas.FindAsync(id);
   if (pizza is null)
   {
      return Results.NotFound();
   }
   db.Pizzas.Remove(pizza);
   await db.SaveChangesAsync();
   return Results.Ok();
});

Đang kiểm tra DELETE

Bây giờ, hãy thử xóa một mục bằng cách sử dụng giao diện Swagger.

Trong đơn vị này, bạn đã thêm EF Core vào một ứng dụng API tối thiểu hiện có và sử dụng cơ sở dữ liệu trong bộ nhớ để lưu trữ dữ liệu. Tiếp theo, bạn sẽ tìm hiểu cách sử dụng cơ sở dữ liệu thực để lưu trữ dữ liệu sao cho dữ liệu vẫn tồn tại giữa các lần tắt ứng dụng.