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

简介: - 状态- 自动变更检测- 不查询删除和更新- 并发

2.4.6 EF Core -- 更新

  • 状态
  • 自动变更检测
  • 不查询删除和更新
  • 并发

状态

  • Entity State
  • Property State

Entity State

  • Added 添加
  • Unchanged 没有变化
  • Modified 已修改
  • Deleted 已删除
  • Detached 未跟踪

35.jpg

Property State

  • IsModified
  • CurrentValue
  • OriginValue

自动变更检测

  • 使用自动变更检测完成确定字段的更新
  • 使用自动变更检测完成任意字段的更新

使用自动变更检测完成确定字段的更新

ProjectController

[HttpPatch]
[Route("{id}")]
public async Task<ActionResult<Project>> SetTitleAsync(string id, [FromQuery] string title, CancellationToken cancellationToken)
{
    // 查询实体信息
    var origin = await _lighterDbContext.Projects.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);

    // 修改实体属性
    origin.Title = title;

    // 数据提交保存
    await _lighterDbContext.SaveChangesAsync();

    return origin;
}

修改分组信息

// 查询实体信息
var originGroup = await _lighterDbContext.ProjectGroups.Where(g => g.ProjectId == id).ToListAsync(cancellationToken: cancellationToken);

// 修改实体属性
foreach (var group in originGroup)
{
    group.Name = $"{title} - {group.Name}";
}

查询项目信息时带出分组信息

[HttpGet]
public async Task<IEnumerable<Project>> GetListAsync(CancellationToken cancellationToken)
{
    return await _lighterDbContext.Projects.Include(p => p.Groups).ToListAsync(cancellationToken);
}

使用自动变更检测完成任意字段的更新

[HttpPatch]
[Route("{id}")]
public async Task<ActionResult<Project>> SetAsync(string id, CancellationToken cancellationToken)
{
    // 查询实体信息
    var origin = await _lighterDbContext.Projects.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);
    var properties = _lighterDbContext.Entry(origin).Properties.ToList();

    // 修改实体属性
    foreach (var query in HttpContext.Request.Query)
    {
        var property = properties.FirstOrDefault(p => p.Metadata.Name == query.Key);
        if (property == null)
            continue;

        var currentValue = Convert.ChangeType(query.Value.First(), property.Metadata.ClrType);

        _lighterDbContext.Entry(origin).Property(query.Key).CurrentValue = currentValue;
        _lighterDbContext.Entry(origin).Property(query.Key).IsModified = true;
    }

    // 数据提交保存
    await _lighterDbContext.SaveChangesAsync(cancellationToken);

    return origin;
}

不查询删除和更新

删除之前先查询

var id = 1;
using(var db = new entityContext())
{
    var entity = db.dbset.FirstOrDefault(e=>e.ID == id);
    if(entity != null)
    {
        db.dbset.Remove(entity);
        db.SaveChanges();
    }
}

不查询删除

var id = 1;
using(var db = new entityContext())
{
    var entity = new Entity{ID = id};
    
    db.dbset.Attach(entity);
    db.dbset.Remove(entity);
    db.SaveChanges();
}

不查询更新

try
{
    using(var db = new dbContext())
    {
        var entity = new myEntity{PageID = pageid};
        db.Pages.Attach(entity);// added
        
        entity.Title = "new title";// modified, isModified=true
        entity.Url = "new-url";
        
        db.SaveChanges();
    }
}
catch(DataException)
{
    
}

并发

乐观处理:系统认为数据的更新在大多数情况下是不会产生冲突的,只在数据库更新操作提交的时候才对数据作冲突检测(推荐)

悲观处理:根据命名即对数据库进行操作更新时,对操作持悲观保守的态度,认为产生数据冲突的可能性很大,需要先对请求的数据加锁再进行相关操作

在 Entity 中添加行版本号字段

/// <summary>
/// 行版本号
/// </summary>
[Timestamp]
public byte[] RowVersion { get; set; }

每次对数据进行更新的时候,都会产生最新的版本号,如果更新的时候查询的版本号与之前的版本号不一致,就会报错

在 UpdateAsync 方法中的查询和更新中间如果数据库的行版本号发生了修改,就会报错

ProjectController

[HttpPut]
[Route("{id")]
public async Task<ActionResult<Project>> UpdateAsync(string id, [FromBody] Project project, CancellationToken cancellationToken)
{
    var origin = await _lighterDbContext.Projects.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);

    if (origin == null)
        return NotFound();

    _lighterDbContext.Entry(origin).CurrentValues.SetValues(project);

    await _lighterDbContext.SaveChangesAsync(cancellationToken);
    return origin;
}

通过客户端传入行版本号,解决前端浏览器数据覆盖问题

_lighterDbContext.Entry(origin).Property(p => p.RowVersion).OriginalValue = project.RowVersion;

2.4.7 EF Core -- 迁移

生成 SQL 脚本

从空白开始生成sql脚本  
dotnet ef migrations script


生成指定版本到最新版本的sql 
dotnet ef migrations script AddNewTables


从A-B版本生成迁移SQL脚本 
dotnet ef migrations script AddNewTables AddAuditTable

2.4.8 EF Core -- 其他

database-first

dotnet ef dbcontext scaffold "server=172.0.0.1;port=7306;user=root;password=root123456@;database=lighter" Pomelo.EntityFrameworkCore.MySql -o Models

GitHub源码链接:

https://github.com/MINGSON666/Personal-Learning-Library/tree/main/ArchitectTrainingCamp/LighterApi

目录
相关文章
|
1月前
|
Cloud Native Serverless API
微服务架构实战指南:从单体应用到云原生的蜕变之路
🌟蒋星熠Jaxonic,代码为舟的星际旅人。深耕微服务架构,擅以DDD拆分服务、构建高可用通信与治理体系。分享从单体到云原生的实战经验,探索技术演进的无限可能。
微服务架构实战指南:从单体应用到云原生的蜕变之路
|
1月前
|
Java Linux 虚拟化
【Docker】(1)Docker的概述与架构,手把手带你安装Docker,云原生路上不可缺少的一门技术!
1. Docker简介 1.1 Docker是什么 为什么docker会出现? 假定您在开发一款平台项目,您的开发环境具有特定的配置。其他开发人员身处的环境配置也各有不同。 您正在开发的应用依赖于您当前的配置且还要依赖于某些配置文件。 您的企业还拥有标准化的测试和生产环境,且具有自身的配置和一系列支持文件。 **要求:**希望尽可能多在本地模拟这些环境而不产生重新创建服务器环境的开销 问题: 要如何确保应用能够在这些环境中运行和通过质量检测? 在部署过程中不出现令人头疼的版本、配置问题 无需重新编写代码和进行故障修复
327 2
|
1月前
|
人工智能 API 数据库
Semantic Kernel .NET 架构学习指南
本指南系统解析微软Semantic Kernel .NET架构,涵盖核心组件、设计模式与源码结构,结合实战路径与调试技巧,助你从入门到贡献开源,掌握AI编排开发全栈技能。
198 2
|
1月前
|
人工智能 Kubernetes Cloud Native
Higress(云原生AI网关) 架构学习指南
Higress 架构学习指南 🚀写在前面: 嘿,欢迎你来到 Higress 的学习之旅!
464 0
|
7月前
|
运维 Cloud Native 测试技术
极氪汽车云原生架构落地实践
随着极氪数字业务的飞速发展,背后的 IT 技术也在不断更新迭代。极氪极为重视客户对服务的体验,并将系统稳定性、业务功能的迭代效率、问题的快速定位和解决视为构建核心竞争力的基石。
|
4月前
|
缓存 Cloud Native Java
Java 面试微服务架构与云原生技术实操内容及核心考点梳理 Java 面试
本内容涵盖Java面试核心技术实操,包括微服务架构(Spring Cloud Alibaba)、响应式编程(WebFlux)、容器化(Docker+K8s)、函数式编程、多级缓存、分库分表、链路追踪(Skywalking)等大厂高频考点,助你系统提升面试能力。
244 0
|
6月前
|
人工智能 Cloud Native 容灾
深圳农商银行三代核心系统全面投产 以云原生架构筑牢数字化转型基石
深圳农商银行完成第三代核心系统全面上云,日均交易超3000万笔,峰值处理效率提升2倍以上。扎根深圳70余年,与阿里云共建“两地三中心”分布式云平台,实现高可用体系及全栈护航。此次云原生转型为行业提供可复制样本,未来将深化云计算与AI合作,推动普惠金融服务升级。
494 17
|
6月前
|
存储 Cloud Native 关系型数据库
PolarDB开源:云原生数据库的架构革命
本文围绕开源核心价值、社区运营实践和技术演进路线展开。首先解读存算分离架构的三大突破,包括基于RDMA的分布式存储、计算节点扩展及存储池扩容机制,并强调与MySQL的高兼容性。其次分享阿里巴巴开源治理模式,涵盖技术决策、版本发布和贡献者成长体系,同时展示企业应用案例。最后展望技术路线图,如3.0版本的多写多读架构、智能调优引擎等特性,以及开发者生态建设举措,推荐使用PolarDB-Operator实现高效部署。
369 3

热门文章

最新文章

下一篇
oss云网关配置