.NET Core 构建Rest服务实验手册(三)

在本系列的 上一篇文章 中,我们介绍了 Controller 类及相关的注解,比如 Router, ApiController 等,并演示了如何构建自己的 Web API。本文将继续完善示例,演示如何在 Controller 中存取数据库。

在.NET Core 中,存取数据库最简单的方法就是使用 Entity Framework Core。 Entity Framework Core(简称: EF Core) 是.NET Core 中 O/RM 的具体实现,使用它可以极大的简化数据库应用的开发,提高开发效率。

建立 DbContext

DbContext 是一个和数据库进行会话的类,它封装了对针对数据库包含的表的CRUD相关操作,是 EF Core 的一个核心类。使用DbContext 可以完成以下一些操作:

  1. 管理数据库连接
  2. 配置实体和实体间的关系
  3. 查询数据库中的数据
  4. 保存数据到数据库中
  5. 变化跟踪
  6. 缓存
  7. 事务管理

安装 EntityFrameworkCore

要使用 , 需要先在项目中增加对它的依赖,执行以下命令:

1
dotnet add package Microsoft.EntityFrameworkCore --version 3.1.4

系统安装:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
正在确定要还原的项目…
Writing C:\Users\stu\AppData\Local\Temp\tmp748A.tmp
info : 正在将包“Microsoft.EntityFrameworkCore”的 PackageReference 添加到项目“D:\stu\TodoApi\TodoApi.csproj”。
info : 正在还原 D:\stu\TodoApi\TodoApi.csproj 的包...
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore/index.json 351 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore/3.1.4/microsoft.entityframeworkcore.3.1.4.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore/3.1.4/microsoft.entityframeworkcore.3.1.4.nupkg 56 毫秒
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.bcl.asyncinterfaces/index.json
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.bcl.hashcode/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.componentmodel.annotations/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 335 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.abstractions/3.1.4/microsoft.entityframeworkcore.abstractions.3.1.4.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/system.diagnostics.diagnosticsource/index.json 343 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/system.diagnostics.diagnosticsource/4.7.1/system.diagnostics.diagnosticsource.4.7.1.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.abstractions/3.1.4/microsoft.entityframeworkcore.abstractions.3.1.4.nupkg 93 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.logging/index.json 440 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.logging/3.1.4/microsoft.extensions.logging.3.1.4.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/system.diagnostics.diagnosticsource/4.7.1/system.diagnostics.diagnosticsource.4.7.1.nupkg 113 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/system.componentmodel.annotations/index.json 491 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/system.componentmodel.annotations/4.7.0/system.componentmodel.annotations.4.7.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.logging/3.1.4/microsoft.extensions.logging.3.1.4.nupkg 46 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection/index.json 508 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection/3.1.4/microsoft.extensions.dependencyinjection.3.1.4.nupkg
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.configuration.binder/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.options/index.json
info : OK https://api.nuget.org/v3-flatcontainer/system.componentmodel.annotations/4.7.0/system.componentmodel.annotations.4.7.0.nupkg 55 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection/3.1.4/microsoft.extensions.dependencyinjection.3.1.4.nupkg 57 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/system.collections.immutable/index.json 635 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/system.collections.immutable/1.7.1/system.collections.immutable.1.7.1.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/system.collections.immutable/1.7.1/system.collections.immutable.1.7.1.nupkg 64 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection.abstractions/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.logging.abstractions/index.json 324 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.logging.abstractions/3.1.4/microsoft.extensions.logging.abstractions.3.1.4.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.options/index.json 363 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.configuration.binder/index.json 366 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.options/3.1.4/microsoft.extensions.options.3.1.4.nupkg
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.configuration.binder/3.1.4/microsoft.extensions.configuration.binder.3.1.4.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.logging.abstractions/3.1.4/microsoft.extensions.logging.abstractions.3.1.4.nupkg 50 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.options/3.1.4/microsoft.extensions.options.3.1.4.nupkg 43 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.configuration.binder/3.1.4/microsoft.extensions.configuration.binder.3.1.4.nupkg 48 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.primitives/index.json
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.configuration/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection.abstractions/index.json 314 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection.abstractions/3.1.4/microsoft.extensions.dependencyinjection.abstractions.3.1.4.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.dependencyinjection.abstractions/3.1.4/microsoft.extensions.dependencyinjection.abstractions.3.1.4.nupkg 50 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.configuration/index.json 265 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.configuration/3.1.4/microsoft.extensions.configuration.3.1.4.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.primitives/index.json 307 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.primitives/3.1.4/microsoft.extensions.primitives.3.1.4.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.configuration/3.1.4/microsoft.extensions.configuration.3.1.4.nupkg 44 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.primitives/3.1.4/microsoft.extensions.primitives.3.1.4.nupkg 51 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.configuration.abstractions/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.caching.memory/index.json 1424 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.caching.memory/3.1.4/microsoft.extensions.caching.memory.3.1.4.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.caching.memory/3.1.4/microsoft.extensions.caching.memory.3.1.4.nupkg 43 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.caching.abstractions/index.json
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.bcl.hashcode/index.json 1543 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.bcl.hashcode/1.1.0/microsoft.bcl.hashcode.1.1.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.configuration.abstractions/index.json 571 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.configuration.abstractions/3.1.4/microsoft.extensions.configuration.abstractions.3.1.4.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.configuration.abstractions/3.1.4/microsoft.extensions.configuration.abstractions.3.1.4.nupkg 54 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.caching.abstractions/index.json 573 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.extensions.caching.abstractions/3.1.4/microsoft.extensions.caching.abstractions.3.1.4.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.extensions.caching.abstractions/3.1.4/microsoft.extensions.caching.abstractions.3.1.4.nupkg 47 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.bcl.hashcode/1.1.0/microsoft.bcl.hashcode.1.1.0.nupkg 1232 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.analyzers/index.json 2821 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.analyzers/3.1.4/microsoft.entityframeworkcore.analyzers.3.1.4.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.entityframeworkcore.analyzers/3.1.4/microsoft.entityframeworkcore.analyzers.3.1.4.nupkg 62 毫秒
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.bcl.asyncinterfaces/index.json 6368 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/microsoft.bcl.asyncinterfaces/1.1.1/microsoft.bcl.asyncinterfaces.1.1.1.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/microsoft.bcl.asyncinterfaces/1.1.1/microsoft.bcl.asyncinterfaces.1.1.1.nupkg 478 毫秒
info : 正在安装 Microsoft.Extensions.Configuration.Abstractions 3.1.4。
info : 正在安装 Microsoft.Extensions.Configuration 3.1.4。
info : 正在安装 Microsoft.Extensions.Primitives 3.1.4。
info : 正在安装 Microsoft.Extensions.Caching.Abstractions 3.1.4。
info : 正在安装 Microsoft.EntityFrameworkCore.Abstractions 3.1.4。
info : 正在安装 Microsoft.EntityFrameworkCore 3.1.4。
info : 正在安装 Microsoft.Extensions.Configuration.Binder 3.1.4。
info : 正在安装 Microsoft.Extensions.Options 3.1.4。
info : 正在安装 Microsoft.Extensions.Logging.Abstractions 3.1.4。
info : 正在安装 Microsoft.Extensions.DependencyInjection.Abstractions 3.1.4。
info : 正在安装 Microsoft.Bcl.AsyncInterfaces 1.1.1。
info : 正在安装 Microsoft.EntityFrameworkCore.Analyzers 3.1.4。
info : 正在安装 Microsoft.Bcl.HashCode 1.1.0。
info : 正在安装 Microsoft.Extensions.Caching.Memory 3.1.4。
info : 正在安装 Microsoft.Extensions.DependencyInjection 3.1.4。
info : 正在安装 Microsoft.Extensions.Logging 3.1.4。
info : 正在安装 System.Collections.Immutable 1.7.1。
info : 正在安装 System.ComponentModel.Annotations 4.7.0。
info : 正在安装 System.Diagnostics.DiagnosticSource 4.7.1。
info : 包“Microsoft.EntityFrameworkCore”与项目“D:\Study\dotnet\adv\TodoApi\TodoApi.csproj”中指定的所有框架均兼容。
info : 包“Microsoft.EntityFrameworkCore”(版本为 3.1.4)的 PackageReference 已添加到文件“D:\Study\dotnet\adv\TodoApi\TodoApi.csproj”。
info : 正在提交还原...
info : 将资产文件写入磁盘。路径: D:\Study\dotnet\adv\TodoApi\obj\project.assets.json
log : 已还原 D:\stu\TodoApi\TodoApi.csproj (用时 9.39 sec)。

使用 EntityFrameworkCore

在本示中,我们这样定义 DbContext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace TodoApi.Dao
{
public class TodoContext : DbContext
{

public TodoContext(DbContextOptions<TodoContext> options)
: base(options)
{
}

public DbSet<Todo> Todos { get; set; }

}
}

可以看到在 TodoConetext 中,定义了一个 DbSet的属性用于封装与 Todo 实体相关的操作。后面我们将用 Todos 属性完成对 Todo 表的 CRUD 操作。

注册 TodoContext

要在 Web API 中使用 DbContext, 最简单的方法就是把 DbContext 注册到 IServiceCollection 中。

打开项目根目录中的 Startup.cs 文件,在 ConfigureServices 中增加注册 DbContext 的代码:

1
2
3
4
5
6
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<TodoContext>(opt =>
opt.UseInMemoryDatabase("Todo-DB"));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

第3,4行是新增的注册 TodoContext 的代码。这里我们使用了内存数据库,也可以换成其它类型的数据库,比如: MS SQL Server, MySQL 等。

在本教程中,使用内存数据库,因此需要首先安装 UseInMemoryDatabase 包,执行:

1
dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 3.1.4

修改 Web API

在 Controller 中,需要做以下一些修改:

  1. 增加一个TodoContext的属性,以便于在类中其它方法中调用。
1
private readonly TodoContext _context;
  1. 修改 TodoController 的构造方法,使用 .NET Core 中的依赖注入,在构造方法中将 TodoContext 的实例注入到类中:
1
2
3
4
public TodoController(TodoContext context)
{
_context = context;
}
  1. 为了演示查询的效果,我们在构造方法中构造一条 Todo 的数据。
1
2
3
4
5
if (_context.Todos.Count() == 0)
{
_context.Todos.Add(new Todo { Title = "task1", Desc = "description for task1", IsComplete = false });
_context.SaveChanges();
}
  1. 最后,修改 Get 方法。在上一篇文章中,使用自己构造的数组作为返回值
1
2
3
4
5
6
7
8
9
[HttpGet]
public ActionResult<IEnumerable<Todo>> Get()
{
List<Todo> todos = new List<Todo>();
todos.Add(new Todo() {Id = 1, Title = "task1", Desc = "description for task1", IsComplete = false});
todos.Add(new Todo() {Id = 2, Title = "task2", Desc = "description for task2", IsComplete = false});

return todos;
}

现在,我们将这段代码改为查询数据库返回结果

1
2
3
4
5
[HttpGet]
public ActionResult<IEnumerable<Todo>> Get()
{
return _context.Todos.ToList();
}

修改完毕,执行 dotnet run 以运行程序,打开浏览器,访问 https://localhost:5001/api/todo, 可以看到我们初始插入数据库的数据被查询出来。

1
[{"id":1,"title":"task1","desc":"description for task1","isComplete":false}]

最后,附上修改后 TodoController 的完整代码,便于学员对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
namespace TodoApi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class TodoController : ControllerBase
{

private readonly TodoContext _context;

public TodoController(TodoContext context)
{
_context = context;

if (_context.Todos.Count() == 0)
{
_context.Todos.Add(new Todo { Title = "task1", Desc = "description for task1", IsComplete = false });
_context.SaveChanges();
}
}

[HttpGet]
public ActionResult<IEnumerable<Todo>> Get()
{
return _context.Todos.ToList();
}

}
}

下一步

下一步,将演示如何处理 Web API 中的参数。

本文标题:.NET Core 构建Rest服务实验手册(三)

文章作者:梅老师

发布时间:2019年08月20日 - 22:08

最后更新:2020年09月16日 - 08:09

原始链接:https://www.mls-tech.info/dotnet/aspnet-core-practice-manual-3/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。