.NET 云原生架构师训练营(模块二 基础巩固 EF Core 基础与配置)--学习笔记

简介: - 连接字符串- 异步编程- 日志- DbContext池- 类和配置表- 属性和列配置- 并发token- 索引

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 是自动生成的

028.jpg

通过数据批注方式添加创建时间,修改时间默认值

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

启动程序,新增一条数据,可以看到创建时间,修改时间默认值

029.jpg

并发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/MINGSON666/Personal-Learning-Library/tree/main/ArchitectTrainingCamp/LighterApi

目录
相关文章
|
5天前
|
Cloud Native 安全 数据安全/隐私保护
云原生架构下的微服务治理与挑战####
随着云计算技术的飞速发展,云原生架构以其高效、灵活、可扩展的特性成为现代企业IT架构的首选。本文聚焦于云原生环境下的微服务治理问题,探讨其在促进业务敏捷性的同时所面临的挑战及应对策略。通过分析微服务拆分、服务间通信、故障隔离与恢复等关键环节,本文旨在为读者提供一个关于如何在云原生环境中有效实施微服务治理的全面视角,助力企业在数字化转型的道路上稳健前行。 ####
|
4天前
|
Cloud Native 安全 API
云原生架构下的微服务治理策略与实践####
—透过云原生的棱镜,探索微服务架构下的挑战与应对之道 本文旨在探讨云原生环境下,微服务架构所面临的关键挑战及有效的治理策略。随着云计算技术的深入发展,越来越多的企业选择采用云原生架构来构建和部署其应用程序,以期获得更高的灵活性、可扩展性和效率。然而,微服务架构的复杂性也带来了服务发现、负载均衡、故障恢复等一系列治理难题。本文将深入分析这些问题,并提出一套基于云原生技术栈的微服务治理框架,包括服务网格的应用、API网关的集成、以及动态配置管理等关键方面,旨在为企业实现高效、稳定的微服务架构提供参考路径。 ####
24 5
|
6天前
|
Kubernetes 负载均衡 Cloud Native
云原生架构下的微服务治理策略
随着云原生技术的不断成熟,微服务架构已成为现代应用开发的主流选择。本文探讨了在云原生环境下实施微服务治理的策略和方法,重点分析了服务发现、负载均衡、故障恢复和配置管理等关键技术点,以及如何利用Kubernetes等容器编排工具来优化微服务的部署和管理。文章旨在为开发者提供一套实用的微服务治理框架,帮助其在复杂的云环境中构建高效、可靠的分布式系统。
19 5
|
6天前
|
负载均衡 监控 Cloud Native
云原生架构下的微服务治理策略与实践####
在数字化转型浪潮中,企业纷纷拥抱云计算,而云原生架构作为其核心技术支撑,正引领着一场深刻的技术变革。本文聚焦于云原生环境下微服务架构的治理策略与实践,探讨如何通过精细化的服务管理、动态的流量调度、高效的故障恢复机制以及持续的监控优化,构建弹性、可靠且易于维护的分布式系统。我们将深入剖析微服务治理的核心要素,结合具体案例,揭示其在提升系统稳定性、扩展性和敏捷性方面的关键作用,为读者提供一套切实可行的云原生微服务治理指南。 ####
|
6天前
|
消息中间件 缓存 Cloud Native
云原生架构下的性能优化实践与挑战####
随着企业数字化转型的加速,云原生架构以其高度解耦、弹性伸缩和快速迭代的特性,成为现代软件开发的首选模式。本文深入探讨了云原生环境下性能优化的关键策略与面临的主要挑战,通过案例分析,揭示了如何有效利用容器化、微服务、动态调度等技术手段提升应用性能,同时指出了在复杂云环境中确保系统稳定性和高效性的难题,为开发者和架构师提供了实战指南。 ####
18 3
|
6天前
|
运维 Kubernetes Cloud Native
深入理解云原生架构:从理论到实践
【10月更文挑战第38天】本文将引导读者深入探索云原生技术的核心概念,以及如何将这些概念应用于实际的软件开发和运维中。我们将从云原生的基本定义出发,逐步展开其背后的设计哲学、关键技术组件,并以一个具体的代码示例来演示云原生应用的构建过程。无论你是云原生技术的初学者,还是希望深化理解的开发者,这篇文章都将为你提供有价值的见解和实操指南。
|
6天前
|
Kubernetes Cloud Native 持续交付
云原生技术在现代应用架构中的实践与思考
【10月更文挑战第38天】随着云计算的不断成熟和演进,云原生(Cloud-Native)已成为推动企业数字化转型的重要力量。本文从云原生的基本概念出发,深入探讨了其在现代应用架构中的实际应用,并结合代码示例,展示了云原生技术如何优化资源管理、提升系统弹性和加速开发流程。通过分析云原生的优势与面临的挑战,本文旨在为读者提供一份云原生转型的指南和启示。
19 3
|
6天前
|
运维 Kubernetes Cloud Native
云原生技术在现代应用架构中的实践与挑战####
本文深入探讨了云原生技术的核心概念、关键技术组件及其在实际项目中的应用案例,分析了企业在向云原生转型过程中面临的主要挑战及应对策略。不同于传统摘要的概述性质,本摘要强调通过具体实例揭示云原生技术如何促进应用的灵活性、可扩展性和高效运维,同时指出实践中需注意的技术债务、安全合规等问题,为读者提供一幅云原生技术实践的全景视图。 ####
|
6天前
|
运维 Kubernetes Cloud Native
云原生技术:容器化与微服务架构的完美结合
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术以其灵活性和高效性成为企业的新宠。本文将深入探讨云原生的核心概念,包括容器化技术和微服务架构,以及它们如何共同推动现代应用的发展。我们将通过实际代码示例,展示如何在Kubernetes集群上部署一个简单的微服务,揭示云原生技术的强大能力和未来潜力。
|
16天前
|
弹性计算 Kubernetes Cloud Native
云原生架构下的微服务设计原则与实践####
本文深入探讨了在云原生环境中,微服务架构的设计原则、关键技术及实践案例。通过剖析传统单体架构面临的挑战,引出微服务作为解决方案的优势,并详细阐述了微服务设计的几大核心原则:单一职责、独立部署、弹性伸缩和服务自治。文章还介绍了容器化技术、Kubernetes等云原生工具如何助力微服务的高效实施,并通过一个实际项目案例,展示了从服务拆分到持续集成/持续部署(CI/CD)流程的完整实现路径,为读者提供了宝贵的实践经验和启发。 ####

热门文章

最新文章