.NET 云原生架构师训练营(模块二 基础巩固 EF Core 基础与配置)--学习笔记
2.4.3 EF Core -- 基础与配置
- 连接字符串
- 异步编程
- 日志
- DbContext池
- 类和配置表
- 属性和列配置
- 并发token
- 索引
Entity Framework Core:https://docs.microsoft.com/zh-cn/ef/core/
连接字符串
连接字符串:https://docs.microsoft.com/zh-cn/ef/core/miscellaneous/connection-strings
在 ASP.NET Core 配置系统非常灵活,并且可以将连接字符串存储在 appsettings.json 、环境变量、用户密钥存储或其他配置源中
appsettings.json
{
  "ConnectionStrings": {
    "BloggingDatabase": "Server=(localdb)\\mssqllocaldb;Database=EFGetStarted.ConsoleApp.NewDb;Trusted_Connection=True;"
  },
}
异步编程
异步编程:https://docs.microsoft.com/zh-cn/ef/core/miscellaneous/async
当在数据库中执行查询时,异步操作将避免阻止线程。 异步操作对于在丰富的客户端应用程序中保持响应式 UI 非常重要,并且还可以增加 web 应用程序中的吞吐量,在这些应用程序中,它们可释放线程以处理 web 应用程序中的其他请求
var blog = new Blog { Url = "http://sample.com" };
context.Blogs.Add(blog);
await context.SaveChangesAsync();
日志
日志:https://docs.microsoft.com/zh-cn/ef/core/logging-events-diagnostics/extensions-logging?tabs=v3
Entity Framework Core (EF Core) 与完全集成 Microsoft.Extensions.Logging
appsettings.json
"Microsoft.EntityFrameworkCore.Database.Command": "Debug"
启动程序,查询列表,控制台输出
dbug: Microsoft.EntityFrameworkCore.Database.Command[20103]
      Creating DbCommand for 'ExecuteReader'.
dbug: Microsoft.EntityFrameworkCore.Database.Command[20104]
      Created DbCommand for 'ExecuteReader' (10ms).
dbug: Microsoft.EntityFrameworkCore.Database.Command[20100]
      Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT `p`.`Id`, `p`.`CreatedAt`, `p`.`CreatedBy`, `p`.`EndDate`, `p`.`IdentityId`, `p`.`LastUpdateAt`, `p`.`LastUpdateBy`, `p`.`PlanId`, `p`.`StartDate`, `p`.`SupervisorId`, `p`.`TenantId`, `p`.`Title`, `p`.`UserId`
      FROM `Projects` AS `p`
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (82ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT `p`.`Id`, `p`.`CreatedAt`, `p`.`CreatedBy`, `p`.`EndDate`, `p`.`IdentityId`, `p`.`LastUpdateAt`, `p`.`LastUpdateBy`, `p`.`PlanId`, `p`.`StartDate`, `p`.`SupervisorId`, `p`.`TenantId`, `p`.`Title`, `p`.`UserId`
      FROM `Projects` AS `p`
dbug: Microsoft.EntityFrameworkCore.Database.Command[20300]
      A data reader was disposed.
DbContext池
AddDbContextPool 启用实例的池 DbContext 。 上下文池可以通过重复使用上下文实例,而不是为每个请求创建新实例,从而提高大规模方案(如 web 服务器)的吞吐量。
services.AddDbContextPool<LighterDbContext>(options =>
{
    options.UseMySql(Configuration.GetConnectionString("LighterDbContext"));
});
AddDbContextPool使用时,在请求上下文实例时,EF 首先检查池中是否有可用的实例。 请求处理完成后,实例的任何状态都将被重置,并且实例本身会返回池中。
避免在维护状态的应用程序中使用上下文池。 例如,不应在请求之间共享的上下文中的私有字段。 在将上下文实例添加到池中之前,EF Core 仅重置它知道的状态。
除高度优化的方案外,池的性能提升通常可以忽略不计。
类和配置表
实体类型:https://docs.microsoft.com/zh-cn/ef/core/modeling/entity-types?tabs=data-annotations
在模型中包含类型
class MyContext : DbContext
{
    // 对应一张表(推荐)
    public DbSet<Blog> Blogs { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // 对应一张表
        modelBuilder.Entity<AuditEntry>();
    }
}
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    public List<Post> Posts { get; set; }
}
public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public Blog Blog { get; set; }
}
public class AuditEntry
{
    public int AuditEntryId { get; set; }
    public string Username { get; set; }
    public string Action { get; set; }
}
从模型中排除类型
[NotMapped]
public class BlogMetadata
{
    public DateTime LoadedFromDatabase { get; set; }
}
从迁移中排除
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<IdentityUser>()
        .ToTable("AspNetUsers", t => t.ExcludeFromMigrations());
}
属性和列配置
- 包含和排除的属性
- 列名
- 键
- 自动生成列
包含和排除的属性
实体属性:https://docs.microsoft.com/zh-cn/ef/core/modeling/entity-properties?tabs=data-annotations
数据批注
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    [NotMapped]
    public DateTime LoadedFromDatabase { get; set; }
}
Fluent API
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Ignore(b => b.LoadedFromDatabase);
}
列名
数据批注
public class Blog
{
    [Column("blog_id")]
    public int BlogId { get; set; }
    public string Url { get; set; }
}
Fluent API (推荐)
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.BlogId)
        .HasColumnName("blog_id");
}
键
键:https://docs.microsoft.com/zh-cn/ef/core/modeling/keys?tabs=data-annotations
按照约定,将名为 Id 或的属性 Id 配置为实体的主键。
class Car
{
    public string Id { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
}
class Truck
{
    public string TruckId { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
}
可以将单个属性配置为实体的主键
数据批注
class Car
{
    [Key]
    public string LicensePlate { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
}
Fluent API
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Car>()
        .HasKey(c => c.LicensePlate);
}
自动生成列
生成的值:https://docs.microsoft.com/zh-cn/ef/core/modeling/generated-properties?tabs=data-annotations
通过 Fluent API 的方式添加自增列
LighterDbContext
modelBuilder.Entity<Project.Project>().Property(p => p.Id).ValueGeneratedOnAdd();
注释控制器中 Id 的赋值
ProjectController
//project.Id = Guid.NewGuid().ToString();
新增一条数据,返回 Id 是自动生成的

通过数据批注方式添加创建时间,修改时间默认值
Entity
/// <summary>
/// 创建时间
/// </summary>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public DateTime CreatedAt { get; set; }
/// <summary>
/// 最后修改时间
/// </summary>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public DateTime LastUpdateAt { get; set; }
更新数据库
dotnet ef migrations add ChangeLastUpdateByToString
dotnet ef database update
启动程序,新增一条数据,可以看到创建时间,修改时间默认值

并发token
并发标记:https://docs.microsoft.com/zh-cn/ef/core/modeling/concurrency?tabs=data-annotations
配置为并发标记的属性用于实现乐观并发控制。
数据批注
public class Person
{
    public int PersonId { get; set; }
    [ConcurrencyCheck]
    public string LastName { get; set; }
    public string FirstName { get; set; }
}
Fluent API
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Person>()
        .Property(p => p.LastName)
        .IsConcurrencyToken();
}
Timestamp/rowversion (推荐)
Timestamp/rowversion 是一个属性,在每次插入或更新行时,数据库会自动为其生成新值。 此属性也被视为并发标记,这确保了在你查询行后,如果正在更新的行发生了更改,则会出现异常。
数据批注
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    [Timestamp]
    public byte[] Timestamp { get; set; }
}
Fluent API
class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .Property(p => p.Timestamp)
            .IsRowVersion();
    }
}
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    public byte[] Timestamp { get; set; }
}
索引
索引:https://docs.microsoft.com/zh-cn/ef/core/modeling/indexes
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .HasIndex(b => b.Url);
}
为多个列指定索引
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Person>()
        .HasIndex(p => new { p.FirstName, p.LastName });
}
GitHub源码链接:
https://github.com/MingsonZheng/ArchitectTrainingCamp/tree/main/LighterApi
课程链接
https://appsqsyiqlk5791.h5.xiaoeknow.com/v1/course/video/v_5f39bdb8e4b01187873136cf?type=2

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。
如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。
.NET 云原生架构师训练营(模块二 基础巩固 EF Core 基础与配置)--学习笔记的更多相关文章
- .NET 云原生架构师训练营(模块一 架构师与云原生)--学习笔记
		目录 什么是软件架构 软件架构的基本思路 单体向分布式演进.云原生.技术中台 1.1 什么是软件架构 1.1.1 什么是架构? Software architecture = {Elements, F ... 
- .NET 云原生架构师训练营(建立系统观)--学习笔记
		目录 目标 ASP .NET Core 什么是系统 什么是系统思维 系统分解 什么是复杂系统 作业 目标 通过整体定义去认识系统 通过分解去简化对系统的认识 ASP .NET Core ASP .NE ... 
- .NET 云原生架构师训练营(权限系统 RGCA 架构设计)--学习笔记
		目录 项目核心内容 实战目标 RGCA 四步架构法 项目核心内容 无代码埋点实现对所有 API Action 访问控制管理 对 EF Core 实体新增.删除.字段级读写控制管理 与 Identity ... 
- .NET 云原生架构师训练营(模块二 基础巩固 敏捷开发)--学习笔记
		2.7.1 敏捷开发 敏捷介绍 敏捷的起源 敏捷软件开发宣言 敏捷开发十二原则 生命周期对比 敏捷开发的特点 敏捷的发展 敏捷的核心 敏捷的起源 2001年,17个老头子在一起一边滑雪,一边讨论工作, ... 
- .NET 云原生架构师训练营(模块二 基础巩固 MongoDB 介绍和基础)--学习笔记
		2.5.1 MongoDB -- 介绍 mysql vs mongo 快速开始 mysql vs mongo 对比 mysql mongo 数据存储 table 二维表结构,需要预先定义结构 json ... 
- .NET 云原生架构师训练营(模块二 基础巩固 MongoDB 问答系统)--学习笔记
		2.5.6 MongoDB -- 问答系统 MongoDB 数据库设计 API 实现概述 MongoDB 数据库设计 设计优化 内嵌(mongo)还是引用(mysql) 数据一致性 范式:将数据分散到 ... 
- .NET 云原生架构师训练营(模块二 基础巩固 Scrum 团队)--学习笔记
		2.7.3 Scrum 团队 理想的环境 团队章程 如何组建 Scrum 团队 产品待办事项列表 用户故事 敏捷开发流程 理想的环境 5-9人 100% 跨职能 在一起 自组织 自组织 目标 授权 沟 ... 
- .NET 云原生架构师训练营(模块二 基础巩固 EF Core 更新和迁移)--学习笔记
		2.4.6 EF Core -- 更新 状态 自动变更检测 不查询删除和更新 并发 状态 Entity State Property State Entity State Added 添加 Uncha ... 
- .NET 云原生架构师训练营(模块二 基础巩固 MongoDB 写入和查询)--学习笔记
		2.5.3 MongoDB -- 写入和查询 写入 查询 查找操作符 逻辑操作符 其他 嵌套对象 数组 游标方法 写入 https://docs.mongodb.com/manual/tutorial ... 
- .NET 云原生架构师训练营(模块二 基础巩固 MongoDB 更新和删除)--学习笔记
		2.5.4 MongoDB -- 更新和删除 整体更新 更新字段 字段操作 数组操作 删除 https://docs.mongodb.com/manual/reference/operator/upd ... 
随机推荐
- CSS Sticky Footer 几种实现方式
			项目里,有个需求,登录页,信息,需要使用到sticky footer布局,刚好,巩固下这个技术: 核心代码: 播客: https://www.jb51.net/css/676798.html 视频:h ... 
- Https 原理与工作流程及证书链校验
			本文为博主原创,未经允许不得转载: 目录 HTTP传输三大风险 安全通信原则 HTTPS定义 TLS/SSL 协议及加密算法 HTTPS工作流程 HTTPS协议和HTTP协议的区别 CA机构 证书链校 ... 
- 为R Markdown配置TinyTex编译环境
			技术背景 在前面一篇博客中,我们介绍了一些关于在Windows系统上安装R Studio来编写R Markdown,最后编译成Beamer的演示文档的过程.而在Windows系统的使用过程中发现,编译 ... 
- 问题--QT只有全屏的时候才能使用
			1.问题 安装的版本是3.8.0,只有在全屏的时候在编辑界面不会卡,其余情况会直接卡死在这. 2.解决方式 安装了较低版本的3.14.2,解决了上述问题 
- 在Vue中可以使用方括号法获得想要的对象数据吗?
			1.问题 Document {{message}} {{school.name}}{{school[mobile]}} 在这里 {{school.name}}{{school[mobile]}} 不可 ... 
- 【C++】枚举作为类函数返回值时需定义在使用之前
			枚举定义在前,作为函数返回值在后 枚举定义在后,则函数返回值需用普通类型 
- Go-用本地时间解析时间字符串
			Go-用本地时间解析时间字符串 1. 指定本地时区 const ( gLocalTimeZone = "Asia/Shanghai" ) 2. 加载本地时区 var ( gLoca ... 
- Python注释是什么东东
			注释 标注解释,目的是帮助读者理解的文本 也就是说,注释首先是文本,其二是说明,其三是思路,其四是例子注释有两种形式 1. # ... 单行注释 用于对某句语句或语句块进行解释 放在语句块的头行或一个 ... 
- 持续集成指南:Gitlab CI/CD 自动部署前端项目
			前言 之前陆续写了 Gitlab 的安装使用还有 Gitlab CI/CD 的配置使用,已经把 AspNetCore 的后端项目都做了持续集成了,尝到甜头之后,现在前端的项目也要加入自动化部署,所以经 ... 
- [转帖]从小白到精通:揭秘perf工具的全部功能与操作技巧
			https://zhuanlan.zhihu.com/p/664396453  目录 收起 一.引言 二.理解perf工具的基本概念 三.安装与配置perf工具 3.1.不同操作系统的perf工具安 ... 
