.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
在模型中包 ad8 含类型
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; } 56c 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/MINGSON666/Personal-Learning-Library/tree/main/ArchitectTrainingCamp/LighterApi
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。
如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。
- .NET 云原生架构师训练营(模块二 基础巩固 MongoDB 更新和删除)--学习笔记
- .NET 云原生架构师训练营(模块二 基础巩固 MongoDB API重构)--学习笔记
- .NET 云原生架构师训练营(模块二 基础巩固 MongoDB 聚合)--学习笔记
- .NET 云原生架构师训练营(模块二 基础巩固 EF Core 关系)--学习笔记
- .NET 云原生架构师训练营(模块二 基础巩固 RabbitMQ HelloWorld)--学习笔记
- IBatis.net学习笔记_基础配置
- Enterprise Library 4.1 学习笔记( 二)配置应用程序模块
- FPGA学习笔记1-基础与配置
- python基础学习笔记<内建模块与第三方模块>
- Linux 5.4 RHCE Sendmail 学习笔记基础配置
- Hibernate学习笔记(3)基础配置
- .Net学习笔记----2015-07-21(C#基础复习08,模拟移动硬盘U盘等)
- openstack学习笔记八 cinder基础配置
- Unity2.0学习笔记-Unity2.0基础-如何配置Unity2.0容器-运行时配置
- Struts2学习笔记01----初识struts2配置文件和相关基础知识
- Vijava学习笔记之DataCenter(基础配置信息)
- .Net学习笔记----2015-07-08(基础复习和练习02)
- python基础学习笔记<函数式编程与模块>
- react native 学习笔记----使用Android的原生模块
- JAVA并发编程学习笔记------基础构建模块