02020404 EF Core基础04-自增主键、Guid主键、混合自增、Hi/Lo算法、Migration深入、数据库其它迁移命令

news/2025/9/21 21:23:30/文章来源:https://www.cnblogs.com/python-web/p/19104197

02020404 EF Core基础04-自增主键、Guid主键、混合自增、Hi/Lo算法、Migration深入、数据库其它迁移命令

1. 主键无小事(视频3-6)

1.1 自增主键
1、EF Core支持多种主键生成策略:自动增长;Guid;Hi/Lo算法等。
2、自动增长。优点:简单;缺点:数据库迁移以及分布式系统中比较麻烦;并发性能差。long、int等类型主键,默认是自增。因为是数据库生成的值,所以SaveChanges后会自动把主键的值更新到Id属性。试验一下。场景:插入帖子后,自动重定向帖子地址。
3、自增字段的代码中不能为Id赋值,必须保持默认值0,否则运行的时候就会报错。
1.2 重定向到主键示例
// Dog.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace EFCoreDemo
{public class Dog{public long Id { get; set; } //主键public string Name { get; set; }//标题}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// MyDbContext.cs
using Microsoft.EntityFrameworkCore;namespace EFCoreDemo
{class MyDbContext : DbContext{public DbSet<Dog> Dogs { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){string connStr = "Server=.;Database=CoreDataDB;Trusted_Connection=True;MultipleActiveResultSets=true";optionsBuilder.UseSqlServer(connStr);}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);}}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 程序包管理控制台:
PM> add-migration adddog
Build started...
Build succeeded.
To undo this action, use Remove-Migration.
PM> update-database
Build started...
Build succeeded.
Applying migration '20250921003202_adddog'.
Done.
PM> 
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// System.cs
using System;
using System.Threading.Tasks;
using System.Linq;namespace EFCoreDemo
{class Program{static async Task Main(string[] args){using (MyDbContext ctx = new MyDbContext()){Dog dog01 = new Dog();dog01.Name = "abc";Console.WriteLine(dog01.Id); // 插入数据库之前Idctx.Dogs.Add(dog01); // Dogs表插入数据await ctx.SaveChangesAsync(); // 更新数据库Console.WriteLine(dog01.Id); // 插入数据库之后Id}Console.ReadLine();}}
}控制台输出:
0
1说明:SaveChanges之后,会自动把主键的值更新到Id属性。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 程序执行后Dogs表的结果:
Id	Name
1	abc

2. Guid主键

2.1 Guid算法介绍
1、Guid算法(或UUID算法)生成一个全局唯一的Id。适合于分布式系统,在进行多数据库数据合并的时候很简单。优点:简单,高并发,全局唯一;缺点:磁盘空间占用大。
2、Guid值不连续。使用Guid类型做主键的时候,不能把主键设置为聚集索引。因为聚集索引是按照顺序保存主键的,因此用Guid做主键性能差。比如MySQL的InnoDB引擎中主键是强制使用聚集索引的。有的数据库支持部分的连续Guid,比如SQLServer中的NewSequentialId(),但也不能解决问题。在SQLServer等中,不要把Guid主键设置为聚集索引;在MySQL中,插入频繁的表不要用Guid做主键。
3、演示Guid用法:既可以让EF Core给赋值,也可以手动赋值(推荐)。
2.2 C#中的Guid结构体
  • C#中的Guid是一个结构体类型。
using System;namespace EFCoreDemo
{class Program{static void Main(string[] args){Guid g = Guid.NewGuid(); // 使用NewGuid方法创建Guid对象Console.WriteLine(g); // 打印Guid对象Console.WriteLine(g.ToString()); // Guid对象转换为字符串Console.ReadLine();}}
}第一次运行,控制台输出:
7eca159e-8a9a-4bb8-81c5-86153c06ded2
7eca159e-8a9a-4bb8-81c5-86153c06ded2
第二次运行,控制台输出:
829af8ac-fc47-403c-8380-95250f980be4
829af8ac-fc47-403c-8380-95250f980be4
...
第n次运行,控制台输出:
620fe0f9-30b3-4d6d-8c08-115eea77bd52
620fe0f9-30b3-4d6d-8c08-115eea77bd52说明:
1. Guid算法在同一台电脑上任意时刻生成的值不会重复。
2. Guid算法在不同电脑上任意时刻生成的值也不会重复。
3. Guid算法综合了网卡地址,时间等数据综合给出了一个唯一的值。
4. Guid不需要考虑锁,多线程中的重复,因为在任何时候它的值都是唯一的。
5. Guid值用作比较,性能低。同时它占用的空间大。
2.3 EF Core使用Guid
// Dog.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace EFCoreDemo
{public class Bird{public Guid Id { get; set; } //主键public string Name { get; set; }//标题}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// MyDbContext.cs
using Microsoft.EntityFrameworkCore;namespace EFCoreDemo
{class MyDbContext : DbContext{public DbSet<Bird> Birds { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){string connStr = "Server=.;Database=CoreDataDB;Trusted_Connection=True;MultipleActiveResultSets=true";optionsBuilder.UseSqlServer(connStr);}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);}}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 程序包管理控制台:
PM> add-migration addbird
Build started...
Build succeeded.
To undo this action, use Remove-Migration.
PM> update-database
Build started...
Build succeeded.
Applying migration '20250921005202_adddog'.
Done.
PM> 
  • 通过SSMS查看数据库
图片链接丢失
  • Guid类型对应到SQL Server里面就是uniqueidentifier类型。
// 使用EF Core自动的给Guid赋值:Program.cs
using System;
using System.Threading.Tasks;namespace EFCoreDemo
{class Program{static async Task Main(string[] args){using (MyDbContext ctx = new MyDbContext()){Bird b01 = new Bird();b01.Name = "yzk";Console.WriteLine(b01.Id); // 插入数据库之前Id,默认值:00000000-0000-0000-0000-000000000000ctx.Birds.Add(b01); // 给数据库插入数据Console.WriteLine(b01.Id); // @1 在Add之后,在更新到数据库之前,Id的Guid值已经有了。1e89ee64-dae4-4d33-5717-08ddf8bb7517await ctx.SaveChangesAsync(); // @2 更新数据库Console.WriteLine(b01.Id); // 插入数据库之后Id。1e89ee64-dae4-4d33-5717-08ddf8bb7517}Console.ReadLine();}}
}控制台输出:
00000000-0000-0000-0000-000000000000
1e89ee64-dae4-4d33-5717-08ddf8bb7517
1e89ee64-dae4-4d33-5717-08ddf8bb7517说明:
1. 在@1处,只要Add之后,EF Core引擎就会给Guid赋值。
2. 在@2处,将Guid值更新到数据库中。
3. 因此Guid值不是数据库赋值的,而是EF Core赋值的。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
using System;
using System.Threading.Tasks;namespace EFCoreDemo
{class Program{static async Task Main(string[] args){using (MyDbContext ctx = new MyDbContext()){Bird b01 = new Bird();b01.Id = Guid.NewGuid(); // 显式的给Guid赋值b01.Name = "abc";Console.WriteLine(b01.Id);ctx.Birds.Add(b01);Console.WriteLine(b01.Id); await ctx.SaveChangesAsync();Console.WriteLine(b01.Id);}Console.ReadLine();}}
}控制台输出:
2c6ccc8e-5760-49b5-8e4b-54ae560cd60c
2c6ccc8e-5760-49b5-8e4b-54ae560cd60c
2c6ccc8e-5760-49b5-8e4b-54ae560cd60c说明:没有显式指定Guid值,EF Core会自动指定一个默认的。如果有显式指定Guid值,那么就用显式指定的。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
总结:
1. 推荐使用显式指定Guid值,这样可以在Add方法之前提前确定好,便于使用。
2. 对于自增主键,在Add之后值还是为0。只有SaveChangesAsync之后才会增加,因为自增是在数据库里面完成自增的,不是由EF Core完成的。

3. 主键其它方案

3.1 混合自增和Guid(非复合主键)
  • 用自增列做物理的主键,而用Guid列做逻辑上的主键。把自增列设置为表的主键,而在业务上查询数据时候把Guid当主键用。在和其他表关联以及和外部系统通讯的时候(比如前端显示数据的标识的时候)都是使用Guid列。不仅保证了性能,而且利用了Guid的优点,而且减轻了主键自增性导致主键值可被预测带来的安全性问题。
3.2 Hi/Lo算法
  • EF Core支持Hi/Lo算法来优化自增列。主键值由两部分组成:高位(Hi)和低位(Lo),高位由数据库生成,两个高位之间间隔若干个值,由程序在本地生成低位,低位的值在本地自增生成。不同进程或者集群中不同服务器获取的Hi值不会重复,而本地进程计算的Lo则可以保证可以在本地高效率的生成主键值。但是HiLo算法不是EF Core的标准。

4. Migration深入(视频3-7)

1、使用迁移脚本,可以对当前连接的数据库执行编号更高的迁移,这个操作叫做“向上迁移”(Up),也可以执行把数据库回退到旧的迁移,这个操作叫“向下迁移”(Down)。
2、除非有特殊需要,否则不要删除Migrations文件夹下的代码。
3、进一步分析Migrations下的代码。分析Up、Down等方法。查看Migration编号。
4、查看数据库的__EFMigrationsHistory表:记录当前数据库曾经应用过的迁移脚本,按顺序排列。
4.1 初始的EF Core代码
  • 先将当前CoreDataDB数据库中所有数据表清空
// Person.cs
namespace EFCoreDemo
{class Person{public long Id { get; set; } //主键public string Name { get; set; }//标题}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// PersonConfig.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;namespace EFCoreDemo
{class PersonConfig : IEntityTypeConfiguration<Person>{public void Configure(EntityTypeBuilder<Person> builder){builder.ToTable("T_Persons");builder.Property(p => p.Name).IsRequired();}}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// MyDbContext.cs
using Microsoft.EntityFrameworkCore;namespace EFCoreDemo
{class MyDbContext : DbContext{public DbSet<PersonConfig> Dogs { get; set; }public DbSet<Person> Birds { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){string connStr = "Server=.;Database=CoreDataDB;Trusted_Connection=True;MultipleActiveResultSets=true";optionsBuilder.UseSqlServer(connStr);}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);}}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// Program.cs
using System;
using System.Threading.Tasks;namespace EFCoreDemo
{class Program{static void Main(string[] args){Console.ReadLine();}}
}
4.2 演示Migration的迁移
  • step1 → 初始的migration,并更新到数据库。
// 程序包管理器控制台
PM>  add-migration init
Build started...
Build succeeded.
To undo this action, use Remove-Migration.
PM> update-database
Build started...
Build succeeded.
Applying migration '20250921035714_init'.
Done.
PM> 
  • step2 → 查看解决方案资源管理器中Migration文件夹下的20250921035714_init下两个文件
// 执行step1中的代码之后,解决方案资源管理器会自动生成迁移脚本:20250921035714_init.cs
using Microsoft.EntityFrameworkCore.Migrations;namespace EFCoreDemo.Migrations
{public partial class init : Migration{protected override void Up(MigrationBuilder migrationBuilder) // @1.1 往上迁移{migrationBuilder.CreateTable( // @1.2 创建表name: "T_Persons",columns: table => new{Id = table.Column<long>(type: "bigint", nullable: false).Annotation("SqlServer:Identity", "1, 1"),Name = table.Column<string>(type: "nvarchar(max)", nullable: false)},constraints: table =>{table.PrimaryKey("PK_T_Persons", x => x.Id);});}protected override void Down(MigrationBuilder migrationBuilder) // @2.1 往下迁移{migrationBuilder.DropTable( // @2.2 删除表name: "T_Persons");}}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
20250921035714_init.Designer.cs
// <auto-generated />
using EFCoreDemo;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;namespace EFCoreDemo.Migrations
{[DbContext(typeof(MyDbContext))][Migration("20250921035714_init")]partial class init{protected override void BuildTargetModel(ModelBuilder modelBuilder){
#pragma warning disable 612, 618modelBuilder.HasAnnotation("Relational:MaxIdentifierLength", 128).HasAnnotation("ProductVersion", "5.0.4").HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);modelBuilder.Entity("EFCoreDemo.Person", b =>{b.Property<long>("Id").ValueGeneratedOnAdd().HasColumnType("bigint").HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);b.Property<string>("Name").IsRequired().HasColumnType("nvarchar(max)");b.HasKey("Id");b.ToTable("T_Persons");});
#pragma warning restore 612, 618}}
}说明:非必要(即使不用了)也不要将Migration中的cs文件删除,便于回退。
  • step3 → 给Person类增加一个属性
// Person.cs
namespace EFCoreDemo
{class Person{public long Id { get; set; } //主键public string Name { get; set; }//标题public double Height { get; set; } // 身高}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 程序包管理器控制台
PM>  add-migration addheight
Build started...
Build succeeded.
To undo this action, use Remove-Migration.
PM>
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 执行step1中的代码之后,解决方案资源管理器会自动生成迁移脚本:20250921044404_addheight.cs
using Microsoft.EntityFrameworkCore.Migrations;namespace EFCoreDemo.Migrations
{public partial class addheight : Migration{protected override void Up(MigrationBuilder migrationBuilder){migrationBuilder.AddColumn<double>( // 增加1列name: "Height",table: "T_Persons",type: "float",nullable: false,defaultValue: 0.0);}protected override void Down(MigrationBuilder migrationBuilder){migrationBuilder.DropColumn( // 删除1列name: "Height",table: "T_Persons");}}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 程序包管理器控制台
PM> update-database
Build started...
Build succeeded.
Applying migration '20250921044404_addheight'.
Done.
PM> 
  • step4 → 通过SSMS查看__EFMigrationsHistory表
图片链接丢失
MigrationId	             ProductVersion
20250921035714_init		     5.0.4
20250921044404_addheight	 5.0.4说明:
1. MigrationId → 与解决方案资源管理器中的迁移脚本对应
2. ProductVersion → 当前EF Core的版本
  • step5 → 此时如果通过SSMS主动删除数据表20250921044404_addheight这一项,重新再执行update-database会报错。
    • 因为数据表中已经删了20250921044404_addheigh,此时执行update-database实际执行的是20250921035714_init.cs这一版。
    • 在数据表中已经有增加的height这一列,而20250921035714_init.cs这一版没有Height属性,因此会冲突产生错误。
  • step6 → 通过SSMS将删除的数据重新恢复到数据表中。拆了 → 修好。
4.3 总结
  • 资源管理器中的Migration和__EFMigrationsHistory数据表非必要不要删除,最好保留。

5. 数据库其它迁移命令(视频3-8)

1、Update-Database XXX 
把数据库恢复到XXX的状态,迁移脚本不动。
2、Remove-migration
删除最后一次的迁移脚本
3、Script-Migration
生成迁移SQL代码。有了Update-Database 为什么还要生成SQL脚本。
可以生成版本D到版本F的SQL脚本:
Script-Migration D F
生成版本D到最新版本的SQL脚本:Script-Migration D

结尾

书籍:ASP.NET Core技术内幕与项目实战

视频:https://www.bilibili.com/video/BV1pK41137He

著:杨中科

ISBN:978-7-115-58657-5

版次:第1版

发行:人民邮电出版社

※敬请购买正版书籍,侵删请联系85863947@qq.com※

※本文章为看书或查阅资料而总结的笔记,仅供参考,如有错误请留言指正,谢谢!※

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/909061.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

02020403 EF Core基础03-Fluent API、Data Annotation、两种配置的选择

02020403 EF Core基础03-Fluent API、Data Annotation、两种配置的选择 1. FluentAPI哪些不该用(视频3-4) 1.1 约定配置 主要规则: 1:表名采用DbContext中的对应的DbSet的属性名。 2:数据表列的名字采用实体类属性…

深入解析:Python(1)|| 超基础语法(格式,输入输出,变量,字符串,运算符)

深入解析:Python(1)|| 超基础语法(格式,输入输出,变量,字符串,运算符)2025-09-21 21:23 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflo…

深入解析:STM32-FreeRTOS操作系统-任务管理

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Java中异步任务的执行方式有几种?

在Java中,异步任务的执行方式有多种,每种方式适用于不同的场景和需求。以下是常见的几种实现方式:Thread类 最基础的方式是直接使用Thread类创建线程执行任务:new Thread(() -> {// 异步执行的任务System.out.p…

mysql数据库自增ID为int类型超过范围

mysql数据库自增ID为int类型超过范围mysql数据的自增加的id(int)类型,超过范围:数据自增加ID,为int类型,超过范围,就插入数据库失败;怎么解决? 由于数据比较大, 1.第一个简单粗暴:把int变为(BIGINT)不用迁…

202508_浙江省网络安全测试职业职工技能竞赛_misc-1

流量分析,RE,XORTags:流量分析,RE,XOR 0x00. 题目 你是一名资深的网络安全分析取证师,受命调查一家IT公司近期遭遇的一起严重网络安全事件。 该公司主要业务是为中小型企业提供定制化管理系统和数据分析服务。 由…

python爬虫测试

python爬虫测试0.背景:要下合适自己的驱动,不然都是报错!!你需要完成以下两步:检查你的 Chrome 浏览器版本。打开 Chrome,在地址栏输入 chrome://settings/help。 你会看到你的 Chrome 版本号,例如 版本 120.0.…

广二联考题解补全计划:

第十七套: T1:取模性质,倍增 T2: DP优化,状态优化 T3:容斥原理,数位DP T1: 首先先提一个关于取模的性质,一个数对一个比它小的数取模,大小一定减半,考虑对 $ \frac {n}{2}$ 分治即可。 我们先预处理出来每个数…

如何在 C# 中将文本转换为 Word 以及将 Word 转换为文本 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Chapter 8 Contour / Shape Detection

def getContours(img):contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)for cnt in contours:area = cv2.contourArea(cnt)print(area)if area > 500:# -1 代表所有的轮廓c…

【左程云算法笔记016】双端队列-双链表和固定数组实现 - 教程

【左程云算法笔记016】双端队列-双链表和固定数组实现 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Cons…

LeetCode 几道 Promises 和 Time 的题目 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

[硬件电路-232]:FET(场效应管)的核心机制是通过栅极电压调控半导体“沟道“中的载流子浓度与分布,进而控制源极与漏极之间的电流大小 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

java相关问题:面向对象入门2与类的识别

1. 关于 static 修饰符 应该用 static 修饰的方法: *不依赖于特定对象的实例状态:执行的操作不访问或修改对象的实例变量。 *工具类方法:常用于定义工具类中的方法,这些方法提供通用功能,无需创建类实例。 *工厂方…

EXCEL自动调整列宽的快捷键

在 Excel 中,自动调整列宽的快捷键是:Windows 系统:先选中要调整的列(可选中单列或多列),然后按下 Alt + H + O + I(依次按下这些键)。 Mac 系统:先选中要调整的列,然后按下 Command + Option + H + O + I。…

【C++实战⑬】解锁C++文件操作:从基础到实战的进阶之路 - 实践

【C++实战⑬】解锁C++文件操作:从基础到实战的进阶之路 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Co…

破解塔吊顶升高危难题!让事故率降 50%、审批快 70%

在建筑施工领域,塔吊顶升作业作为关键且高危的环节,长期以来饱受诸多痛点的困扰,严重影响施工安全与进度。传统模式下,人工对塔吊顶升作业的审查多依赖现场巡检,然而人力有限,在忙碌的施工现场,难以做到时刻紧盯…

logicFlow________文档2

# LogicFlow 官方指南 - 自定义连线与事件处理## 📖 概述LogicFlow 是滴滴开源的一款流程图编辑框架,具有强大的扩展性和自定义能力。本文档基于LogicFlow官网最新版本,详细介绍如何实现自定义连线、自定义事件处理…

CF2086D Even String

题目链接:Problem - D - Codeforces 本身是一道数学题,我们可以把字符串中的奇数项和偶数项分开,形成两条序列 A 和 B。易知一种字母一定在同一条序列上。 假如说在 A 序列上分配了 \(a,b,c\) 三种字母,\(sum = c_…

logicflow___文档3

# LogicFlow 流程图编辑器开发文档## 📖 概述这是一个基于 LogicFlow 的流程图编辑器完整开发指南,包含详细的代码示例和实现方案。该编辑器支持节点创建、连接线绘制、关系管理等功能。## 🚀 快速开始### 1. 安装…