了解如何将数据库添加到最小 API 应用程序。
基于 ASP.NET Core 生成的最小 API 可以使用 Entity Framework (EF) Core 轻松地与大量数据库集成。
将了解如何使用 EF Core 将数据持久保存到内存数据库,然后再保存到 SQLite。 还将了解如何使用 EF Core 来查询数据库。
向最小 API 应用程序添加数据库支持。
大多数重要的 Web 应用程序都需要对数据可靠地运行创建、读取、更新和删除 (CRUD) 操作。 它们还需要在应用程序重启期间保留这些更改。 尽管有各种选项可用于在 .NET 应用程序中永久保留数据,但 Entity Framework (EF) Core 是一个用户友好型解决方案,非常适合许多 .NET 应用程序。
EF Core 是 .NET 应用程序的轻型、可扩展、开源和跨平台的数据访问技术。
EF Core 可以用作对象关系映射器:
EF Core 支持大量常见数据库,包括 SQLite、MySQL、PostgreSQL、Oracle 和 Microsoft SQL Server。
使用 EF Core 时,数据访问是通过使用模型来执行的。 模型由实体类和表示数据库会话的上下文对象构成。 上下文对象允许查询并保存数据。
在此场景中,将实现一个比萨饼存储管理 API,因此你将使用 Pizza
实体类。 存储中的比萨饼具有名称和说明。 它们还需要 ID,以便 API 和数据库识别它们。 你将在应用程序中使用的 Pizza
实体类可识别比萨饼:
namespace PizzaStore.Models
{
public class Pizza
{
public int Id { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
}
}
此应用程序只有一个实体类,但大多数应用程序将有多个实体类。 上下文类负责查询数据并将其保存到实体类,以及用于创建和管理数据库连接。
配置 EF Core 后,可以使用它对实体类执行 CRUD 操作。 然后,可以针对 C# 类进行开发,并将数据库操作委托给上下文类。 数据库提供程序反过来将其转换为特定于数据库的查询语言。 例如,关系数据库的 SQL。 即使上下文中已存在结果中返回的实体,也始终对数据库执行查询。
上下文对象公开每个实体类型的集合类。 在前面的示例中,上下文类将 Pizza
对象的集合公开为 Pizzas
。 假设有一个上下文类实例,则可以在数据库中查询所有比萨饼:
var pizzas = await db.Pizzas.ToListAsync();
可以使用相同的上下文对象插入新比萨饼:
await db.pizzas.AddAsync(
new Pizza { ID = 1, Name = "Pepperoni", Description = "The classic pepperoni pizza" });
删除操作很简单。 它们只需要删除项的 ID:
var pizza = await db.pizzas.FindAsync(id);
if (pizza is null)
{
//Handle error
}
db.pizzas.Remove(pizza);
同样,可以更新现有比萨饼:
int id = 1;
var updatepizza = new Pizza { Name = "Pineapple", Description = "Ummmm?" })
var pizza = await db.pizzas.FindAsync(id);
if (pizza is null)
{
//Handle error
}
pizza.Item = updatepizza.Item;
pizza.IsComplete = updatepizza.IsComplete;
await db.SaveChangesAsync();
EF Core 包含可用于测试应用程序的内存数据库提供程序。 内存数据库提供程序对于测试和开发非常有用,但不应在生产中使用。 在接下来的单元中,你将使用内存数据库提供程序来创建数据库并对其执行 CRUD 操作。
此模块使用 .NET 6.0 SDK。 通过在首选终端中运行以下命令,确保你已安装 .NET 6.0:
dotnet --list-sdks
将显示类似于下面的输出:
3.1.100 [C:\program files\dotnet\sdk]
5.0.100 [C:\program files\dotnet\sdk]
6.0.100 [C:\program files\dotnet\sdk]
确保列出了以 6
开头的版本。
首先,需要创建一个项目。 已安装 .NET 6,现已准备就绪。 将数据持久性添加到比萨饼管理 API。
通过运行 dotnet new
创建 Web API:
dotnet new web -o PizzaStore -f net6.0
输入以下命令,以转到 PizzaStore 目录:
cd PizzaStore
安装 Swashbuckle 包:
dotnet add package Swashbuckle.AspNetCore --version 6.2.3
创建 Pizza.cs 文件并在其中提供以下内容:
namespace PizzaStore.Models
{
public class Pizza
{
public int Id { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
}
}
前面的 Pizza
类是一个表示比萨饼的简单对象。 此代码是数据模型。 稍后将使用 Entity Framework (EF) Core 将此数据模型映射到数据库表。
打开 Program.cs,并添加代码:
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();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "PizzaStore API V1");
});
app.MapGet("/", () => "Hello World!");
app.Run();
Visual Studio Code 可能会提示你添加资产以调试项目。 单击对话框中的“Yes
”。
若要将项存储在待办事项列表中,请安装 EntityFrameworkCore.InMemory
包。
在终端窗口中,输入以下代码以添加 EF Core InMemory 包:
dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 6.0
PS C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\ASP.NET\PizzaStore> dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 6.0
正在确定要还原的项目…
Writing C:\Users\a-xiaobodou\AppData\Local\Temp\tmp2762.tmp
info : X.509 certificate chain validation will use the default trust store selected by .NET.
info : 正在将包“Microsoft.EntityFrameworkCore.InMemory”的 PackageReference 添加到项目“C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\ASP.NET\PizzaStore\PizzaStore.csproj”。
info : 正在还原 C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\ASP.NET\PizzaStore\PizzaStore.csproj 的包...
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.inmemory/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.inmemory/index.json 923 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.inmemory/6.0.0/microsoft.entityframeworkcore.inmemory.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.inmemory/6.0.0/microsoft.entityframeworkcore.inmemory.6.0.0.nupkg 76 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore/index.json 291 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore/6.0.0/microsoft.entityframeworkcore.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore/6.0.0/microsoft.entityframeworkcore.6.0.0.nupkg 68 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.abstractions/index.json
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.analyzers/index.json
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.caching.memory/index.json
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection/index.json
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.logging/index.json
info : GET https://api.nuget.org/v3-flatcontainer/system.collections.immutable/index.json
info : GET https://api.nuget.org/v3-flatcontainer/system.diagnostics.diagnosticsource/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.abstractions/index.json 283 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.abstractions/6.0.0/microsoft.entityframeworkcore.abstractions.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.abstractions/6.0.0/microsoft.entityframeworkcore.abstractions.6.0.0.nupkg 80 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.analyzers/index.json 576 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.analyzers/6.0.0/microsoft.entityframeworkcore.analyzers.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/system.collections.immutable/index.json 563 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/system.diagnostics.diagnosticsource/index.json 558 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.caching.memory/index.json 590 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.logging/index.json 579 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/system.collections.immutable/6.0.0/system.collections.immutable.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection/index.json 597 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/system.diagnostics.diagnosticsource/6.0.0/system.diagnostics.diagnosticsource.6.0.0.nupkg
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.caching.memory/6.0.0/microsoft.extensions.caching.memory.6.0.0.nupkg
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.logging/6.0.0/microsoft.extensions.logging.6.0.0.nupkg
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection/6.0.0/microsoft.extensions.dependencyinjection.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.analyzers/6.0.0/microsoft.entityframeworkcore.analyzers.6.0.0.nupkg 77 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/system.collections.immutable/6.0.0/system.collections.immutable.6.0.0.nupkg 73 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/system.diagnostics.diagnosticsource/6.0.0/system.diagnostics.diagnosticsource.6.0.0.nupkg 71 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.caching.memory/6.0.0/microsoft.extensions.caching.memory.6.0.0.nupkg 69 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.logging/6.0.0/microsoft.extensions.logging.6.0.0.nupkg 69 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection/6.0.0/microsoft.extensions.dependencyinjection.6.0.0.nupkg 68 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection.abstractions/index.json
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.logging.abstractions/index.json
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.caching.abstractions/index.json
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.options/index.json
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.primitives/index.json
info : GET https://api.nuget.org/v3-flatcontainer/system.runtime.compilerservices.unsafe/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection.abstractions/index.json 276 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection.abstractions/6.0.0/microsoft.extensions.dependencyinjection.abstractions.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.options/index.json 277 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.logging.abstractions/index.json 283 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.options/6.0.0/microsoft.extensions.options.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.caching.abstractions/index.json 292 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.logging.abstractions/6.0.0/microsoft.extensions.logging.abstractions.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.primitives/index.json 308 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.caching.abstractions/6.0.0/microsoft.extensions.caching.abstractions.6.0.0.nupkg
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.primitives/6.0.0/microsoft.extensions.primitives.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/system.runtime.compilerservices.unsafe/index.json 286 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/system.runtime.compilerservices.unsafe/6.0.0/system.runtime.compilerservices.unsafe.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection.abstractions/6.0.0/microsoft.extensions.dependencyinjection.abstractions.6.0.0.nupkg 76 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.options/6.0.0/microsoft.extensions.options.6.0.0.nupkg 72 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.logging.abstractions/6.0.0/microsoft.extensions.logging.abstractions.6.0.0.nupkg 71 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.caching.abstractions/6.0.0/microsoft.extensions.caching.abstractions.6.0.0.nupkg 70 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.primitives/6.0.0/microsoft.extensions.primitives.6.0.0.nupkg 70 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/system.runtime.compilerservices.unsafe/6.0.0/system.runtime.compilerservices.unsafe.6.0.0.nupkg 74 毫秒
info : 已通过内容哈希 xlzi2IYREJH3/m6+lUrQlujzX8wDitm4QGnUu6kUXTQAWPuZY8i+ticFJbzfqaetLA6KR/rO6Ew/HuYD+bxifg== 从 https://api.nuget.org/v3/index.json 安装 Microsoft.Extensions.DependencyInjection.Abstractions 6.0.0 。
info : 已通过内容哈希 9+PnzmQFfEFNR9J2aDTfJGGupShHjOuGw4VUv+JB044biSHrnmCIMD+mJHmb2H7YryrfBEXDurxQ47gJZdCKNQ== 从 https://api.nuget.org/v3/index.json 安装 Microsoft.Extensions.Primitives 6.0.0 。
info : 已通过内容哈希 /iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg== 从 https://api.nuget.org/v3/index.json 安装 System.Runtime.CompilerServices.Unsafe 6.0.0 。
info : 已通过内容哈希 bcz5sSFJbganH0+YrfvIjJDIcKNW7TL07C4d1eTmXy/wOt52iz4LVogJb6pazs7W0+74j0YpXFErvp++Aq5Bsw== 从 https://api.nuget.org/v3/index.json 安装 Microsoft.Extensions.Caching.Abstractions 6.0.0 。
info : 已通过内容哈希 l4zZJ1WU2hqpQQHXz1rvC3etVZN+2DLmQMO79FhOTZHMn8tDRr+WU287sbomD0BETlmKDn0ygUgVy9k5xkkJdA== 从 https://api.nuget.org/v3/index.json 安装 System.Collections.Immutable 6.0.0 。
info : 已通过内容哈希 eIbyj40QDg1NDz0HBW0S5f3wrLVnKWnDJ/JtZ+yJDFnDj90VoPuoPmFkeaXrtu+0cKm5GRAwoDf+dBWXK0TUdg== 从 https://api.nuget.org/v3/index.json 安装 Microsoft.Extensions.Logging 6.0.0 。
info : 已通过内容哈希 WJmphvCn0wue9AX+Wvqj3XZ3ehNi9oyYBFNLtHVNvKqZrcimXBOqLo5RNf1fJWYSLWhOia/vzG4JtkAeZxZ8FQ== 从 https://api.nuget.org/v3/index.json 安装 Microsoft.EntityFrameworkCore.InMemory 6.0.0 。
info : 已通过内容哈希 BqWBL05PUDKwPwLeQCJdc2R4cIUycXV9UmuSjYfux2fcgyet8I2eYnOWlA7NgsDwRVcxW26vxvNQ0wuc8UAcLA== 从 https://api.nuget.org/v3/index.json 安装 Microsoft.EntityFrameworkCore.Analyzers 6.0.0 。
info : 已通过内容哈希 frQDfv0rl209cKm1lnwTgFPzNigy2EKk1BS3uAvHvlBVKe5cymGyHO+Sj+NLv5VF/AhHsqPIUUwya5oV4CHMUw== 从 https://api.nuget.org/v3/index.json 安装 System.Diagnostics.DiagnosticSource 6.0.0 。
info : 已通过内容哈希 k6PWQMuoBDGGHOQTtyois2u4AwyVcIwL2LaSLlTZQm2CYcJ1pxbt6jfAnpWmzENA/wfrYRI/X9DTLoUkE4AsLw== 从 https://api.nuget.org/v3/index.json 安装 Microsoft.Extensions.DependencyInjection 6.0.0 。
info : 已通过内容哈希 MrMLWEw4JsZdkVci0MkkGj+fSjZrXnm3m6UNuIEwytiAAIZPvJs3iPpnzfK4qM7np82W374voYm96q7QCdL0ow== 从 https://api.nuget.org/v3/index.json 安装 Microsoft.EntityFrameworkCore.Abstractions 6.0.0 。
info : 已通过内容哈希 dzXN0+V1AyjOe2xcJ86Qbo233KHuLEY0njf/P2Kw8SfJU+d45HNS2ctJdnEnrWbM9Ye2eFgaC5Mj9otRMU6IsQ== 从 https://api.nuget.org/v3/index.json 安装 Microsoft.Extensions.Options 6.0.0 。
info : 已通过内容哈希 Ve3BlCzhAlVp5IgO3+8dacAhZk1A0GlIlFNkAcfR2TfAibLKWIt5DhVJZfu4YtW+XZ89OjYf/agMcgjDtPxdGA== 从 https://api.nuget.org/v3/index.json 安装 Microsoft.Extensions.Caching.Memory 6.0.0 。
info : 已通过内容哈希 /HggWBbTwy8TgebGSX5DBZ24ndhzi93sHUBDvP1IxbZD7FDokYzdAr6+vbWGjw2XAfR2EJ1sfKUotpjHnFWPxA== 从 https://api.nuget.org/v3/index.json 安装 Microsoft.Extensions.Logging.Abstractions 6.0.0 。
info : 已通过内容哈希 BdHAtHzfQt3rltgSoYamSlHg2qawPtEDT677/bcSJlO8lQ/lj6XWlusM0TOt59O8Sbqm3hAC1a+4cEBxmv56pw== 从 https://api.nuget.org/v3/index.json 安装 Microsoft.EntityFrameworkCore 6.0.0 。
info : 包“Microsoft.EntityFrameworkCore.InMemory”与项目“C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\ASP.NET\PizzaStore\PizzaStore.csproj”中指定的所有框架均兼容。
info : 包“Microsoft.EntityFrameworkCore.InMemory”(版本为 6.0)的 PackageReference 已添加到文件“C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\ASP.NET\PizzaStore\PizzaStore.csproj”。
info : 将资产文件写入磁盘。路径: C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\ASP.NET\PizzaStore\obj\project.assets.json
log : 已还原 C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\ASP.NET\PizzaStore\PizzaStore.csproj (用时 7 sec)。
PS C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\ASP.NET\PizzaStore>
将 using Microsoft.EntityFrameworkCore; 添加到 Program.cs 和 Pizza.cs 文件的顶部。
现在,已将 EF Core 添加到项目,可以将代码连接到要保存和查询的数据。 若要执行此步骤,将创建 PizzaDb
类。 PizzaDb
类将执行以下任务:
Pizza
列表公开你的 Pizzas
属性。UseInMemoryDatabase
连接内存数据库存储。 只要应用运行时,数据就会存储在此处。若要设置内存数据库,请将以下代码添加到 Pizza.cs 类底部(在最后的 } 的上方):
class PizzaDb : DbContext
{
public PizzaDb(DbContextOptions options) : base(options) { }
public DbSet Pizzas { get; set; }
}
DbContext
表示一个连接或会话,用于查询和保存数据库中实体的实例。
将 using PizzaStore.Models; 添加到 Program.cs 文件的顶部。
在 Program.cs 中,调用 AddSwaggerGen
之前,添加以下代码:
builder.Services.AddDbContext(options => options.UseInMemoryDatabase("items"));
若要从比萨饼列表中的项列表中进行读取,请在调用 app.Run(); 之前添加以下代码以添加“/pizza”路由:
app.MapGet("/pizzas", async (PizzaDb db) => await db.Pizzas.ToListAsync());
通过调用 dotnet run 来运行应用。 此操作会生成应用,并将应用托管在 5000-5300 范围内的某个端口上。 HTTPS 会在 7000-7300 范围内为应用选择一个端口。
如果要替代随机端口选择行为,可以设置要在 launchSettings.json 中使用的端口。
dotnet run
下面是输出在终端中的情况:
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: //PizzaStore
在浏览器中转到 https://localhost:{PORT}/swagger。 选择 GET /pizzas 按钮,你会看到列表在 Response body 下为空。
让我们将新任务 POST 到你先前创建的 app.MapGet
下的比萨饼列表。
app.MapPost("/pizza", async (PizzaDb db, Pizza pizza) =>
{
await db.Pizzas.AddAsync(pizza);
await db.SaveChangesAsync();
return Results.Created($"/pizza/{pizza.Id}", pizza);
});
返回到 Swagger,此时应会看到 POST/pizza
。 向比萨饼列表添加新项:
选择“POST /pizza”。
选择“试用”。
将请求正文替换为以下内容:
{
"name": "Pepperoni",
"description": "A classic pepperoni pizza"
}
选择“执行”。
读取列表中的项:
选择“GET /pizzas”。
选择“试用”。
选择“执行”。
Response body 将包含刚刚添加的项。
[
{
"id": 1,
"name": "Pepperoni",
"description": "A classic pepperoni pizza"
}
]
若要根据 id
GET 项目,请将代码添加到前面创建的 app.MapPost
路由下。
app.MapGet("/pizza/{id}", async (PizzaDb db, int id) => await db.Pizzas.FindAsync(id));
若要查看此内容,可以访问 https://localhost:{PORT}/pizza/1 或使用 Swagger UI。 由于使用的是内存数据库,在重启应用程序后不会列出前面创建的比萨饼,因此需要再次输入。
若要更新现有项目,请将代码添加到你创建的 GET /pizza/{id} 路由下:
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();
});
在 Swagger UI 中选择“PUT /pizza/{id}”。
选择“试用”。
在“ID”文本框中,输入 1。
最后,更新 Request body。 粘贴以下 JSON 并将 name 更改为 Pineapple。
{
"id": 1,
"name": "Pineapple",
}
选择“执行”。
若要测试代码,请滚动回 GET /pizza/{id}。 比萨饼现在的名称为 Pineapple。
若要更新现有项目,请将代码添加到前面创建的 PUT /pizza/{id}
下:
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();
});
现在,请尝试使用 Swagger 接口删除某个项。
将 EF Core 添加到现有的最小 API 应用程序,并使用内存数据库来存储数据。 接下来,你将了解如何使用实际数据库来存储数据,以便在应用程序关闭期间保持数据。
学习了如何将数据持久保存到内存数据库。 将数据持久保存到内存数据库在开发中非常有用。 但是,由于在应用程序重启时所有数据都将丢失,因此它并不适合用于生产。 在生产环境中,应将数据持久保存到数据库,如 SQL Server、MySQL、PostgreSQL 或 SQLite。
通过抽象层(如 Entity Framework (EF) Core)执行数据库访问的好处之一是,它将应用程序与数据库提供程序分离。 你可以更改数据库提供程序,而无需重写数据库访问代码。 你无法在不影响应用程序代码的情况下切换数据库提供程序,但更改会最小化并本地化。
使用 EF Core 的相关优势在于,你可以重用代码、经验和数据访问库,以便与任何其他 EF Core 数据库提供程序一起使用。
EF Core 当前支持超过 20 个数据库提供程序。
通常,将使用以下步骤来实现新数据库提供程序:
在此之前,已将数据保存在内存数据库中。 此数据库在开发应用程序时非常容易设置和使用,但数据不是持久的。 因此,在应用程序重启时数据将丢失。 在部署应用程序之前,需要将数据持久保存到数据库。
将升级应用程序以使用关系数据库来存储数据。 将使用 SQLite 来存储数据。
完成以下部分以设置 SQLite 数据库。
使用 .NET CLI 和 Visual Studio 包管理器 UI,安装下列包:
dotnet add package Microsoft.EntityFrameworkCore.Sqlite --version 6.0
PS C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\ASP.NET\PizzaStore> dotnet add package Microsoft.EntityFrameworkCore.Sqlite --version 6.0
正在确定要还原的项目…
Writing C:\Users\a-xiaobodou\AppData\Local\Temp\tmp9CF1.tmp
info : X.509 certificate chain validation will use the default trust store selected by .NET.
info : 正在将包“Microsoft.EntityFrameworkCore.Sqlite”的 PackageReference 添加到项目“C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\ASP.NET\PizzaStore\PizzaStore.csproj”。
info : 正在还原 C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\ASP.NET\PizzaStore\PizzaStore.csproj 的包...
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.sqlite/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.sqlite/index.json 906 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.sqlite/6.0.0/microsoft.entityframeworkcore.sqlite.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.sqlite/6.0.0/microsoft.entityframeworkcore.sqlite.6.0.0.nupkg 69 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.sqlite.core/index.json
info : GET https://api.nuget.org/v3-flatcontainer/sqlitepclraw.bundle_e_sqlite3/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.sqlite.core/index.json 280 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.sqlite.core/6.0.0/microsoft.entityframeworkcore.sqlite.core.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.sqlite.core/6.0.0/microsoft.entityframeworkcore.sqlite.core.6.0.0.nupkg 67 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.relational/index.json
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.data.sqlite.core/index.json
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencymodel/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencymodel/index.json 566 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencymodel/6.0.0/microsoft.extensions.dependencymodel.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencymodel/6.0.0/microsoft.extensions.dependencymodel.6.0.0.nupkg 71 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/sqlitepclraw.bundle_e_sqlite3/index.json 1215 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/sqlitepclraw.bundle_e_sqlite3/2.0.6/sqlitepclraw.bundle_e_sqlite3.2.0.6.nupkg
info : GET https://api.nuget.org/v3-flatcontainer/system.text.encodings.web/index.json
info : GET https://api.nuget.org/v3-flatcontainer/system.text.json/index.json
info : GET https://api.nuget.org/v3-flatcontainer/system.buffers/index.json
info : GET https://api.nuget.org/v3-flatcontainer/system.memory/index.json
info : OK https://api.nuget.org/v3-flatcontainer/sqlitepclraw.bundle_e_sqlite3/2.0.6/sqlitepclraw.bundle_e_sqlite3.2.0.6.nupkg 72 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/sqlitepclraw.core/index.json
info : GET https://api.nuget.org/v3-flatcontainer/sqlitepclraw.provider.e_sqlite3/index.json
info : GET https://api.nuget.org/v3-flatcontainer/sqlitepclraw.lib.e_sqlite3/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.relational/index.json 924 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.relational/6.0.0/microsoft.entityframeworkcore.relational.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/system.text.encodings.web/index.json 282 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/system.text.encodings.web/6.0.0/system.text.encodings.web.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/system.text.json/index.json 318 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/system.text.json/6.0.0/system.text.json.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.relational/6.0.0/microsoft.entityframeworkcore.relational.6.0.0.nupkg 248 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.data.sqlite.core/index.json 1214 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.data.sqlite.core/6.0.0/microsoft.data.sqlite.core.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/system.buffers/index.json 455 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/system.buffers/4.5.1/system.buffers.4.5.1.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/system.text.json/6.0.0/system.text.json.6.0.0.nupkg 111 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/system.text.encodings.web/6.0.0/system.text.encodings.web.6.0.0.nupkg 200 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.data.sqlite.core/6.0.0/microsoft.data.sqlite.core.6.0.0.nupkg 66 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/system.buffers/4.5.1/system.buffers.4.5.1.nupkg 65 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/sqlitepclraw.lib.e_sqlite3/index.json 555 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/sqlitepclraw.lib.e_sqlite3/2.0.6/sqlitepclraw.lib.e_sqlite3.2.0.6.nupkg
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.configuration.abstractions/index.json
info : OK https://api.nuget.org/v3-flatcontainer/sqlitepclraw.lib.e_sqlite3/2.0.6/sqlitepclraw.lib.e_sqlite3.2.0.6.nupkg 66 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/system.memory/index.json 1187 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/system.memory/4.5.4/system.memory.4.5.4.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/sqlitepclraw.provider.e_sqlite3/index.json 1253 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/sqlitepclraw.core/index.json 1266 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/system.memory/4.5.4/system.memory.4.5.4.nupkg 123 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/sqlitepclraw.core/2.0.6/sqlitepclraw.core.2.0.6.nupkg
info : GET https://api.nuget.org/v3-flatcontainer/sqlitepclraw.provider.e_sqlite3/2.0.6/sqlitepclraw.provider.e_sqlite3.2.0.6.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/sqlitepclraw.core/2.0.6/sqlitepclraw.core.2.0.6.nupkg 135 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/sqlitepclraw.provider.e_sqlite3/2.0.6/sqlitepclraw.provider.e_sqlite3.2.0.6.nupkg 141 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/system.memory/4.5.3/system.memory.4.5.3.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/system.memory/4.5.3/system.memory.4.5.3.nupkg 230 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.configuration.abstractions/index.json 1079 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.configuration.abstractions/6.0.0/microsoft.extensions.configuration.abstractions.6.0.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.configuration.abstractions/6.0.0/microsoft.extensions.configuration.abstractions.6.0.0.nupkg 69 毫秒
info : 已通过内容哈希 Vh8n0dTvwXkCGur2WqQTITvk4BUO8i8h9ucSx3wwuaej3s2S6ZC0R7vqCTf9TfS/I4QkXO6g3W2YQIRFkOcijA== 从 https://api.nuget.org/v3/index.json 安装 SQLitePCLRaw.core 2.0.6 。
info : 已通过内容哈希 cx55qNWk5JmUMZgMfGvfwodW2z/t3Kix7Fbso9BxCPnPVaiVm8k9C4QLjegqJVvuRAA7RZigMYAqeRZ9Q4fWWQ== 从 https://api.nuget.org/v3/index.json 安装 Microsoft.EntityFrameworkCore.Sqlite.Core 6.0.0 。
info : 已通过内容哈希 qWzV9o+ZRWq+pGm+1dF+R7qTgTYoXvbyowRoBxQJGfqTpqDun2eteerjRQhq5PQ/14S+lqto3Ft4gYaRyl4rdQ== 从 https://api.nuget.org/v3/index.json 安装 Microsoft.Extensions.Configuration.Abstractions 6.0.0 。
info : 已通过内容哈希 zssYqiaucyGArZfg74rJuzK0ewgZiidsRVrZTmP7JLNvK806gXg6PGA46XzoJGpNPPA5uRcumwvVp6YTYxtQ5w== 从 https://api.nuget.org/v3/index.json 安装 SQLitePCLRaw.bundle_e_sqlite3 2.0.6 。
info : 已通过内容哈希 3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA== 从 https://api.nuget.org/v3/index.json 安装 System.Memory 4.5.3 。
info : 已通过内容哈希 peXLJbhU+0clVBIPirihM1NoTBqw8ouBpcUsVMlcZ4k6fcL2hwgkctVB2Nt5VsbnOJcPspQL5xQK7QvLpxkMgg== 从 https://api.nuget.org/v3/index.json 安装 SQLitePCLRaw.provider.e_sqlite3 2.0.6 。
info : 已通过内容哈希 TD5QHg98m3+QhgEV1YVoNMl5KtBw/4rjfxLHO0e/YV9bPUBDKntApP4xdrVtGgCeQZHVfC2EXIGsdpRNrr87Pg== 从 https://api.nuget.org/v3/index.json 安装 Microsoft.Extensions.DependencyModel 6.0.0 。
info : 已通过内容哈希 X6MCFkzJOBkcgzT00Bh7SAqbLM2rPuHgCWMivSRiZ0VGVfgf/l8nwGDe9wYSSjXVdw95JUggvWOQLcNfbBFuLA== 从 https://api.nuget.org/v3/index.json 安装 Microsoft.Data.Sqlite.Core 6.0.0 。
info : 已通过内容哈希 Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w== 从 https://api.nuget.org/v3/index.json 安装 System.Text.Encodings.Web 6.0.0 。
info : 已通过内容哈希 Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg== 从 https://api.nuget.org/v3/index.json 安装 System.Buffers 4.5.1 。
info : 已通过内容哈希 1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw== 从 https://api.nuget.org/v3/index.json 安装 System.Memory 4.5.4 。
info : 已通过内容哈希 VwNbLaMpDD9s/tVmK/sivJsYoXdM3ARBjWMtFUXVExZ6AgZxPwSgILF2J4Y9CRvf/r6A0xitvFXQO6HPrZnwrg== 从 https://api.nuget.org/v3/index.json 安装 Microsoft.EntityFrameworkCore.Sqlite 6.0.0 。
info : 已通过内容哈希 rTRzrSbkUXoCGijlT9O7oq7JfuaU1/+VFyfSBjADQuOsfa0FCrWeB8ybue5CDvO/D6uW0kvPvlKfY2kwxXOOdg== 从 https://api.nuget.org/v3/index.json 安装 Microsoft.EntityFrameworkCore.Relational 6.0.0 。
info : 已通过内容哈希 zaJsHfESQvJ11vbXnNlkrR46IaMULk/gHxYsJphzSF+07kTjPHv+Oc14w6QEOfo3Q4hqLJgStUaYB9DBl0TmWg== 从 https://api.nuget.org/v3/index.json 安装 System.Text.Json 6.0.0 。
info : 已通过内容哈希 xlstskMKalKQl0H2uLNe0viBM6fvAGLWqKZUQ3twX5y1tSOZKe0+EbXopQKYdbjJytNGI6y5WSKjpI+kVr2Ckg== 从 https://api.nuget.org/v3/index.json 安装 SQLitePCLRaw.lib.e_sqlite3 2.0.6 。
info : 包“Microsoft.EntityFrameworkCore.Sqlite”与项目“C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\ASP.NET\PizzaStore\PizzaStore.csproj”中指定的所有框架均兼容。
info : 包“Microsoft.EntityFrameworkCore.Sqlite”(版本为 6.0)的 PackageReference 已添加到文件“C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\ASP.NET\PizzaStore\PizzaStore.csproj”。
info : 将资产文件写入磁盘。路径: C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\ASP.NET\PizzaStore\obj\project.assets.json
log : 已还原 C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\ASP.NET\PizzaStore\PizzaStore.csproj (用时 6.69 sec)。
PS C:\Users\a-xiaobodou\OneDrive - Microsoft\Projects\ASP.NET\PizzaStore>
dotnet tool install --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore.Design --version 6.0
若要启用数据库创建,需要完成两个步骤:
在 Program.cs 的应用生成器 var builder = WebApplication.CreateBuilder(args);
下方,添加一个连接字符串。
var connectionString = builder.Configuration.GetConnectionString("Pizzas") ?? "Data Source=Pizzas.db";
在 CRUD 部分,使用的是内存数据库。 现在,要将内存数据库替换为永久性数据库。
将生成服务中的当前内存数据库实现 builder.Services.AddDbContext
替换为此处的 SQLite 数据库:
builder.Services.AddSqlite(connectionString);
利用 EF Core 迁移工具,你现在可以开始首次迁移 InitialCreate
。 在终端窗口中,运行 migrations
命令:
dotnet ef migrations add InitialCreate
EF Core 将在项目目录中创建一个名为“Migrations”的文件夹,该文件夹包含两个文件,其中包含表示数据库迁移的代码。
完成迁移后,可以使用它来创建数据库和架构。
在终端窗口中,运行以下 database update
命令,将迁移应用到数据库:
dotnet ef database update
你应在项目目录中看到新创建的 Pizzas.db 文件。
现在,已经有了一个后备数据库,更改将永久保留。
若要测试应用程序,请在终端窗口中运行 dotnet run
命令,并在 Swagger UI 中与 API 交互。 可以使用 Ctrl+C 命令停止运行应用程序。 在 macOS 上使用 Cmd+C。 然后再次运行该应用程序,并验证更改是否仍然保留。