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池

DbContext池:https://docs.microsoft.com/zh-cn/ef/core/performance/advanced-performance-topics?tabs=with-constant#dbcontext-pooling

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 基础与配置)--学习笔记的更多相关文章

  1. .NET 云原生架构师训练营(模块一 架构师与云原生)--学习笔记

    目录 什么是软件架构 软件架构的基本思路 单体向分布式演进.云原生.技术中台 1.1 什么是软件架构 1.1.1 什么是架构? Software architecture = {Elements, F ...

  2. .NET 云原生架构师训练营(建立系统观)--学习笔记

    目录 目标 ASP .NET Core 什么是系统 什么是系统思维 系统分解 什么是复杂系统 作业 目标 通过整体定义去认识系统 通过分解去简化对系统的认识 ASP .NET Core ASP .NE ...

  3. .NET 云原生架构师训练营(权限系统 RGCA 架构设计)--学习笔记

    目录 项目核心内容 实战目标 RGCA 四步架构法 项目核心内容 无代码埋点实现对所有 API Action 访问控制管理 对 EF Core 实体新增.删除.字段级读写控制管理 与 Identity ...

  4. .NET 云原生架构师训练营(模块二 基础巩固 敏捷开发)--学习笔记

    2.7.1 敏捷开发 敏捷介绍 敏捷的起源 敏捷软件开发宣言 敏捷开发十二原则 生命周期对比 敏捷开发的特点 敏捷的发展 敏捷的核心 敏捷的起源 2001年,17个老头子在一起一边滑雪,一边讨论工作, ...

  5. .NET 云原生架构师训练营(模块二 基础巩固 MongoDB 介绍和基础)--学习笔记

    2.5.1 MongoDB -- 介绍 mysql vs mongo 快速开始 mysql vs mongo 对比 mysql mongo 数据存储 table 二维表结构,需要预先定义结构 json ...

  6. .NET 云原生架构师训练营(模块二 基础巩固 MongoDB 问答系统)--学习笔记

    2.5.6 MongoDB -- 问答系统 MongoDB 数据库设计 API 实现概述 MongoDB 数据库设计 设计优化 内嵌(mongo)还是引用(mysql) 数据一致性 范式:将数据分散到 ...

  7. .NET 云原生架构师训练营(模块二 基础巩固 Scrum 团队)--学习笔记

    2.7.3 Scrum 团队 理想的环境 团队章程 如何组建 Scrum 团队 产品待办事项列表 用户故事 敏捷开发流程 理想的环境 5-9人 100% 跨职能 在一起 自组织 自组织 目标 授权 沟 ...

  8. .NET 云原生架构师训练营(模块二 基础巩固 EF Core 更新和迁移)--学习笔记

    2.4.6 EF Core -- 更新 状态 自动变更检测 不查询删除和更新 并发 状态 Entity State Property State Entity State Added 添加 Uncha ...

  9. .NET 云原生架构师训练营(模块二 基础巩固 MongoDB 写入和查询)--学习笔记

    2.5.3 MongoDB -- 写入和查询 写入 查询 查找操作符 逻辑操作符 其他 嵌套对象 数组 游标方法 写入 https://docs.mongodb.com/manual/tutorial ...

  10. .NET 云原生架构师训练营(模块二 基础巩固 MongoDB 更新和删除)--学习笔记

    2.5.4 MongoDB -- 更新和删除 整体更新 更新字段 字段操作 数组操作 删除 https://docs.mongodb.com/manual/reference/operator/upd ...

随机推荐

  1. 嵌入式Linux必读经典书籍(含下载方式)

    最近,在知乎看到一个问题,"嵌入式Linux有哪些好书推荐".我读研期间也喜欢收藏一些书籍,每次看到京东有活动,总是忍不住想买一些书籍回来. 随着时间越来越久,我买的书越来越多,但 ...

  2. CMake学习,我们怎么从零开始狂写大型项目

    CMake 说明 cmake的定义是什么 ?-----高级编译配置工具 当多个人用不同的语言或者编译器开发一个项目,最终要输出一个可执行文件或者共享库(dll,so等等)这时候神器就出现了-----C ...

  3. python毕业设计选题15例,马上要毕业啦,大家做好准备了没

    Hi,大家好,大四的同学马上要开始毕业设计啦,大家做好准备了没! 学长给大家详细整理了最新的python计算机毕设相关选题,对选题有任何疑问,都可以问学长哦. 1. 网上商城系统 这是一个基于pyth ...

  4. spring-transaction源码分析(1)概述和事务传播级别

    spring-tx概述 spring-tx包使用注解驱动和AOP通知将事务开启.提交/回滚.以及复杂的传播机制封装了起来,开发者不再需要编写事务管理的代码,而是可以只关注自己的业务逻辑. 本文将简单介 ...

  5. [转帖]ramfs、tmpfs、rootfs、ramdisk介绍

    ramfs.tmpfs.rootfs.ramdisk介绍   bootleader--->kernel---->initrd(是xz.cpio.是ramfs的一种,主要是驱动和为了加载ro ...

  6. [转帖]Linux的tmpfs和ramfs

    tmpfs tmpfs是一种虚拟内存文件系统, 它的存储空间在VM里面,现在大多数操作系统都采用了虚拟内存管理机制, VM(Virtual Memory) 是由Linux内核里面的VM子系统管理. V ...

  7. [转帖]探索惊群 ③ - nginx 惊群现象

    https://wenfh2020.com/2021/09/29/nginx-thundering-herd/    nginx  kernel 本文将通过测试,重现 nginx(1.20.1) 的惊 ...

  8. [转帖]Ipmitool跟OS下的ipmi模块之间的关系

    https://www.jianshu.com/p/71614d3288e8 OS下默认加载了ipmi的相关模块 注:此时OS下可以正常使用ipmitool命令访问本机的ipmi 设备. [root@ ...

  9. [转帖]优化命令之iotop命令

    文章目录 引言 一.iotop简介 1.iotop安装 2.iotop语法 3.iotop参数 二.I/O的常用快捷键 三.交互模式 四.iotop示例 1.只显示正在产生I/O的进程 2.显示指定P ...

  10. 【转帖】GPT4All开源的聊天机器人

    GPT4All是一个开源的聊天机器人,它基于LLaMA的大型语言模型训练而成,使用了大量的干净的助手数据,包括代码.故事和对话.它可以在本地运行,不需要云服务或登录,也可以通过Python或Types ...