02020507 EF Core高级07-悲观并发控制、乐观并发控制、EF Core连接MySQL、RowVersion

news/2025/10/11 21:19:21/文章来源:https://www.cnblogs.com/python-web/p/19136002

02020507 EF Core高级07-悲观并发控制、乐观并发控制、EF Core连接MySQL、RowVersion

1. EF Core悲观并发控制(3-38)

1.1 并发控制的概念
1、并发控制:避免多个用户同时操作资源造成的并发冲突问题。举例:统计点击量。
2、最好的解决方案:非数据库解决方案。
3、数据库层面的两种策略:悲观、乐观。
1.2 悲观并发控制
1、悲观并发控制一般采用行锁、表锁等排他锁对资源进行锁定,确保同时只有一个使用者操作被锁定的资源。
2、EF Core没有封装悲观并发控制的使用,需要开发人员编写原生SQL语句来使用悲观并发控制。不同数据库的语法不一样。

2. MySQL悲观并发控制

class House
{public long Id { get; set; }public string Name { get; set; }public string Owner { get; set; }
}
MySQL方案: select * from T_Houses where Id=1 for update
如果有其他的查询操作也使用for update来查询Id=1的这条数据的话,那些查询就会被挂起,一直到针对这条数据的更新操作完成从而释放这个行锁,代码才会继续执行。
2.1 安装MySQL数据库
  • 参考04020101小结
2.2 新建数据库
图片链接丢失
2.3 创建项目并创建数据表
  • 创建.NET Core控制台应用程序PessimisticDemo
// 安装MySQL的依赖包
1. install-package pomelo.entityframeworkcore.mysql -version 5.0.0
2. install-package microsoft.entityframeworkcore.design -version 5.0.7
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// House.cs
namespace PessimisticDemo
{class House{public long Id { get; set; }public string Name { get; set; }public string Owner { get; set; }}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// HouseConfig.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;namespace PessimisticDemo
{class HouseConfig : IEntityTypeConfiguration<House>{public void Configure(EntityTypeBuilder<House> builder){builder.ToTable("T_Houses");builder.Property(h => h.Name).IsRequired(); // Name属性不为空}}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// MyDbContext.cs
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace PessimisticDemo
{class MyDbContext : DbContext{public DbSet<House> Houses { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){base.OnConfiguring(optionsBuilder);var connStr = "server=localhost; user = root; password = 123456; database = mysqldemo";var serverVersion = new MySqlServerVersion(new Version(5, 7, 36));optionsBuilder.UseMySql(connStr, serverVersion);// optionsBuilder.LogTo(Console.WriteLine);}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);}}
}    
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 迁移数据库
PM> add-migration init
Build started...
Build succeeded.
The Entity Framework tools version '5.0.4' is older than that of the runtime '5.0.7'. Update the tools for the latest features and bug fixes.
To undo this action, use Remove-Migration.
PM> update-database
Build started...
Build succeeded.
The Entity Framework tools version '5.0.4' is older than that of the runtime '5.0.7'. Update the tools for the latest features and bug fixes.
Applying migration '20251006064559_init'.
Done.
PM> 
  • 查看如下数据表并添加数据
图片链接丢失
2.4 实现(会有并发问题)
1、锁是和事务相关的,因此通过BeginTransactionAsync()创建一个事务,并且在所有操作完成后调用CommitAsync()提交事务。
2、var h1 = await ctx.Houses.FromSqlInterpolated($"select * from T_Houses where Id=1 for update").SingleAsync();
3、定位到编译完成的exe目录下,运行两个exe程序的实例,分别输入姓名tom和jim。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
using System;
using System.Linq;
using System.Threading;namespace PessimisticDemo
{class Program{static void Main(string[] args){Console.WriteLine("请输入您的名字:");string name = Console.ReadLine();using (MyDbContext ctx = new MyDbContext()){var h01 = ctx.Houses.Single(h => h.Id == 1);if(!string.IsNullOrEmpty(h01.Owner)){if(h01.Owner == name){Console.WriteLine("房子已经被抢到了");}else{Console.WriteLine("房子已经被[" + h01.Owner + "]占了");}return;}h01.Owner = name;Thread.Sleep(10000); // 延时,造成两次输入都占用Console.WriteLine("恭喜你,房子抢到了");ctx.SaveChanges();Console.ReadKey();}}}
}
  • 运行生成的.exe文件,使用2个窗口。等待之后都会显示“房子已经被抢到了"
图片链接丢失
  • 等待10s之后的输出结果
图片链接丢失
  • 查看数据表
"Id"	"Name"	"Owner"
"1"	"1-1-502"	"tom"
"2"	"1-1-101"	
"3"	"2-1-101"	说明:程序显示2个都抢到了,但是数据库中只有tom抢到了。这里就会产生并发的问题。
2.5 实现(无并发问题)
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading;namespace PessimisticDemo
{class Program{static void Main(string[] args){Console.WriteLine("请输入您的名字:");string name = Console.ReadLine();using (MyDbContext ctx = new MyDbContext())using(var tx = ctx.Database.BeginTransaction()) // step1 先启动事务{// var h01 = ctx.Houses.Single(h => h.Id == 1);var h01 = ctx.Houses.FromSqlInterpolated($"select * from houses where Id =1 for update").Single(); // step3 加锁if (!string.IsNullOrEmpty(h01.Owner)){if(h01.Owner == name){Console.WriteLine("房子已经被抢到了");}else{Console.WriteLine("房子已经被[" + h01.Owner + "]占了");}return;}h01.Owner = name;Thread.Sleep(10000); // 延时,造成两次输入都占用Console.WriteLine("恭喜你,房子抢到了");ctx.SaveChanges(); // step4 解锁tx.Commit(); // step2 提交事务Console.ReadKey();}}}
}
  • 继续2.4中操作,查看数据表
"Id"	"Name"	"Owner"
"1"	"1-1-502"	"tom"
"2"	"1-1-101"	
2.6 悲观并发控制的缺点
1、悲观并发控制的使用比较简单;
2、锁是独占、排他的,如果系统并发量很大的话,会严重影响性能,如果使用不当的话,甚至会导致死锁。
3、不同数据库的语法不一样。

3. 乐观并发控制(视频3-39)

3.1 乐观并发控制思路
// 对tom来说
update houses set owner = 'tom' where id = 1 and owner = ''说明:当owner值为空,当影响行数1。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 对jerry来说
update houses set owner = 'jerry' where id = 1 and owner = ''说明:当owner值不为空,影响行数为0。此时会报错:并发修改失败。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
综上:上述是乐观并发控制原理
3.2 乐观控制并发原理
Update T_Houses set Owner=新值
where Id=1 and Owner=旧值
举例子。当Update的时候,如果数据库中的Owner值已经被其他操作者更新为其他值了,那么where语句的值就会为false,因此这个Update语句影响的行数就是0,EF Core就知道“发生并发冲突”了,因此SaveChanges()方法就会抛出DbUpdateConcurrencyException异常。
3.3 乐观并发控制EF Core配置
1、把被并发修改的属性使用IsConcurrencyToken()设置为并发令牌。
2、builder.Property(h => h.Owner).IsConcurrencyToken();
3、catch(DbUpdateConcurrencyException ex)
{var entry = ex.Entries.First();var dbValues = await entry.GetDatabaseValuesAsync();string newOwner = dbValues.GetValue<string>(nameof(House.Owner));Console.WriteLine($"并发冲突,被{newOwner}提前抢走了");
}
3.4 乐观并发控制示例
  • 数据库中信息
图片链接丢失
  • 新建项目:OptimisticDemo
// House.cs
namespace OptimisticDemo
{class House{public long Id { get; set; }public string Name { get; set; }public string Owner { get; set; }}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// HouseConfig.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;namespace OptimisticDemo
{class HouseConfig : IEntityTypeConfiguration<House>{public void Configure(EntityTypeBuilder<House> builder){builder.ToTable("T_Houses");builder.Property(h => h.Name).IsRequired(); // Name属性不为空builder.Property(h => h.Owner).IsConcurrencyToken(); // 设置并发令牌}}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// MyDbContext.cs
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace OptimisticDemo
{class MyDbContext : DbContext{public DbSet<House> Houses { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){base.OnConfiguring(optionsBuilder);var connStr = "server=localhost; user = root; password = 123456; database = mysqldemo";var serverVersion = new MySqlServerVersion(new Version(5, 7, 36));optionsBuilder.UseMySql(connStr, serverVersion);optionsBuilder.LogTo(Console.WriteLine); // 查看日志}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);}}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// OptimisticDemo.csproj
<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><OutputType>Exe</OutputType><TargetFramework>net5.0</TargetFramework></PropertyGroup><ItemGroup><PackageReference Include="microsoft.entityframeworkcore.design" Version="5.0.7"><PrivateAssets>all</PrivateAssets><IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets></PackageReference><PackageReference Include="pomelo.entityframeworkcore.mysql" Version="5.0.0" /></ItemGroup></Project>
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// Program.cs
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading;namespace OptimisticDemo
{class Program{static void Main(string[] args){Console.WriteLine("请输入您的名字:");string name = Console.ReadLine();using (MyDbContext ctx = new MyDbContext()){var h01 = ctx.Houses.Single(h => h.Id == 1);if (!string.IsNullOrEmpty(h01.Owner)){if (h01.Owner == name){Console.WriteLine("房子已经被抢到了");}else{Console.WriteLine("房子已经被[" + h01.Owner + "]占了");}Console.ReadKey();return;}h01.Owner = name;Thread.Sleep(10000);Console.WriteLine("恭喜你,房子抢到了");try{ctx.SaveChanges();}catch (DbUpdateConcurrencyException ex){Console.WriteLine($"并发冲突");}Console.ReadLine();}}}
}
  • 结果演示
图片链接丢失
  • 查看数据库信息
图片链接丢失
3.5 查看并发冲突的值
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading;namespace OptimisticDemo
{class Program{static void Main(string[] args){Console.WriteLine("请输入您的名字:");string name = Console.ReadLine();using (MyDbContext ctx = new MyDbContext()){var h01 = ctx.Houses.Single(h => h.Id == 1);if (!string.IsNullOrEmpty(h01.Owner)){if (h01.Owner == name){Console.WriteLine("房子已经被抢到了");}else{Console.WriteLine("房子已经被[" + h01.Owner + "]占了");}Console.ReadKey();return;}h01.Owner = name;Thread.Sleep(10000);Console.WriteLine("恭喜你,房子抢到了");try{ctx.SaveChanges();}catch (DbUpdateConcurrencyException ex){Console.WriteLine($"并发冲突");var entry1 = ex.Entries.First();string newValue = entry1.GetDatabaseValues().GetValue<string>("Owner");Console.WriteLine("被[" + newValue + "]抢先了");}Console.ReadLine();}}}
}
  • 结果演示
图片链接丢失
3.6 乐观并发总结
1、首先把数据库中Id=1这一行数据中的Owner列的值清空,然后仍然像上一节一样运行两个exe程序的实例,分别输入姓名tom和jim。
2、使用乐观并发控制是在更新的时候检查一下,因此并没有性能问题,并不会产生死锁等问题。
3、开发中推荐使用乐观并发,而不用悲观的锁来实现。

4. 乐观并发控制:RowVersion(视频3-40)

4.1 如果有很多字段都有并发控制
// SQLServer的RowVersion
1、SQLServer数据库可以用一个byte[]类型的属性做并发令牌属性,然后使用IsRowVersion()把这个属性设置为RowVersion类型,这样这个属性对应的数据库列就会被设置为ROWVERSION类型。对于ROWVERSION类型的列,在每次插入或更新行时,数据库会自动为这一行的ROWVERSION类型的列生成新值。
2、在SQLServer中,timestamp和rowversion是同一种类型的不同别名而已。
3、RowVersion是SQL Server特有,其它数据库貌似没有。
4.2 RowVersion原理
class House
{public long Id { get; set; }public string Name { get; set; }public string Owner { get; set; }public byte[] RowVer { get; set; }
}
builder.Property(h => h.RowVer).IsRowVersion();
4.3 RowVersion示例数据库准备
  • 使用SQL Server示例
// OptimisticDemo.csproj
<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><OutputType>Exe</OutputType><TargetFramework>net5.0</TargetFramework></PropertyGroup><ItemGroup><!-- 使用MySQL start--><PackageReference Include="microsoft.entityframeworkcore.design" Version="5.0.7"><PrivateAssets>all</PrivateAssets><IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets></PackageReference><PackageReference Include="pomelo.entityframeworkcore.mysql" Version="5.0.0" /><!-- 使用MySQL end--><!-- 使用SQL Server start--><PackageReference Include="microsoft.entityframeworkcore.sqlserver" Version="5.0.4" /><PackageReference Include="microsoft.entityframeworkcore.tools" Version="5.0.4"><PrivateAssets>all</PrivateAssets><IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets></PackageReference><!-- 使用SQL Server end--></ItemGroup></Project>
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// House.cs
namespace OptimisticDemo
{class House{public long Id { get; set; }public string Name { get; set; }public string Owner { get; set; }public byte[] RowVersion { get; set; } // 设置RowVersion,这里可以取其它属性名。}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// HouseConfig.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;namespace OptimisticDemo
{class HouseConfig : IEntityTypeConfiguration<House>{public void Configure(EntityTypeBuilder<House> builder){builder.ToTable("T_Houses");builder.Property(h => h.Name).IsRequired(); // Name属性不为空// builder.Property(h => h.Owner).IsConcurrencyToken(); // 设置并发令牌builder.Property(b => b.RowVersion).IsRowVersion(); // 与实体类的RowVersion对应,也可以理解为令牌}}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// MyDbContext.cs
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace OptimisticDemo
{class MyDbContext : DbContext{public DbSet<House> Houses { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){base.OnConfiguring(optionsBuilder);/* 连接MySQL startvar connStr = "server=localhost; user = root; password = 123456; database = mysqldemo";var serverVersion = new MySqlServerVersion(new Version(5, 7, 36));optionsBuilder.UseMySql(connStr, serverVersion);连接MySQL end */// 连接SQL Serverstring connStr = "Server=.; Database=CoreDataDB; Trusted_Connection=True; MultipleActiveResultSets=true"; // 连接SQL ServeroptionsBuilder.UseSqlServer(connStr);// optionsBuilder.LogTo(Console.WriteLine); // 查看日志}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);}}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 迁移数据库SQL Server
PM> add-migration init
Build started...
Build succeeded.
The Entity Framework tools version '5.0.4' is older than that of the runtime '5.0.7'. Update the tools for the latest features and bug fixes.
To undo this action, use Remove-Migration.
PM> update-database
Build started...
Build succeeded.
The Entity Framework tools version '5.0.4' is older than that of the runtime '5.0.7'. Update the tools for the latest features and bug fixes.
Applying migration '20251006145439_init'.
Done.
PM> 
  • 查看数据库
图片链接丢失
  • 数据库添加数据
图片链接丢失
  • 查看二进制数据
// step1 → SSMS新建查询
select * from T_Houses
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// step2 → 查询结果
1	8-1-101	NULL	0x00000000000036BC说明:
1. 0x00000000000036BC为二进制数据,由SQL Server自动生成。
2. 对数据行做任何改变,自动生成的二进制数据就会改变。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// step3 → 改变Name值为:7-1-101
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// step4 → 查询结果
Id	Name	Owner	RowVersion
1	7-1-101	NULL	0x00000000000036BD说明:二进制数据自动改变了。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
总结:可以将RowVersion的二进制值视为一个“版本号”
4.4 Program.cs
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading;namespace OptimisticDemo
{class Program{static void Main(string[] args){Console.WriteLine("请输入您的名字:");string name = Console.ReadLine();using (MyDbContext ctx = new MyDbContext()){var h01 = ctx.Houses.Single(h => h.Id == 1);if (!string.IsNullOrEmpty(h01.Owner)){if (h01.Owner == name){Console.WriteLine("房子已经被抢到了");}else{Console.WriteLine("房子已经被[" + h01.Owner + "]占了");}Console.ReadKey();return;}h01.Owner = name;Thread.Sleep(10000);Console.WriteLine("恭喜你,房子抢到了");try{ctx.SaveChanges();}catch (DbUpdateConcurrencyException ex){Console.WriteLine($"并发冲突");var entry1 = ex.Entries.First();string newValue = entry1.GetDatabaseValues().GetValue<string>("Owner");Console.WriteLine("被[" + newValue + "]抢先了");}Console.ReadLine();}}}
}说明:此处代码实现3.5中一样。
  • 结果演示
图片链接丢失
  • 查看数据库
// SSMS查看
Id	Name	Owner	RowVersion
1	7-1-101	jerry	0x00000000000036BE
4.5 RowVersion的优点
builder.Property(h => h.Owner).IsConcurrencyToken(); // 设置并发令牌,适用于单个属性
builder.Property(b => b.RowVersion).IsRowVersion(); // 适用于一个数据行多个属性,只要任何属性改变都能检查到。
4.6 RowVersion在其它数据库中的问题
1、在MySQL等数据库(某些旧版本,貌似5.6版本及以下版本)中虽然也有类似的timestamp类型,但是由于timestamp类型的精度不够,并不适合在高并发的系统。
2、非SQLServer中,可以将并发令牌列的值更新为Guid的值。
3、修改其他属性值的同时,使用h1.RowVer = Guid.NewGuid()手动更新并发令牌属性的值。
4.7 RowVersion总结
1、乐观并发控制能够避免悲观锁带来的性能、死锁等问题,因此推荐使用乐观并发控制而不是悲观锁。
2、如果有一个确定的字段要被进行并发控制,那么使用IsConcurrencyToken()把这个字段设置为并发令牌即可; 
3、如果无法确定一个唯一的并发令牌列,那么就可以引入一个额外的属性设置为并发令牌,并且在每次更新数据的时候,手动更新这一列的值。如果用的是SQLServer数据库,那么也可以采用RowVersion列,这样就不用开发者手动来在每次更新数据的时候,手动更新并发令牌的值了。

结尾

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

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

著:杨中科

ISBN:978-7-115-58657-5

版次:第1版

发行:人民邮电出版社

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

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

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

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

相关文章

linux防火墙操作命令

防火墙操作 Linux系统安装完毕后,系统启动时,防火墙自动启动,防火墙拦截了所有端口的访问。接下来我们就需要学习一下,如何操作防火墙,具体指令如下:操作 指令查看防火墙状态 systemctl status firewalld / fire…

02020506 EF Core高级06-EF Core批量删除更新插入、全局筛选器、软删除、全局筛选的性能问题

02020506 EF Core高级06-EF Core批量删除&更新&插入、全局筛选器、软删除、全局筛选的性能问题 1. EF Core如何批量删除、更新、插入(视频3-36) 1.1 EF Core中插入数据(单条) 1、EF Core中不支持高效的删除…

完整教程:游标查询在对话历史场景下的独特优势

完整教程:游标查询在对话历史场景下的独特优势pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &…

[论文笔记] A Contemporary Survey of Large Language Model Assisted Program Analysis

Survey 站在 security 研究者的角度来关注 LLM + 程序分析的如下几个方向:静态分析:在不同的下游应用上评估 LLM 的作用,下游应用包括 vulnerability detection,malware detection,program verification, static …

C语言入门教程 | 第一讲:C语言零基础入门教程:第一个代码到变量运算详解

C语言入门教程 | 第一讲:C语言零基础入门教程:第一个代码到变量运算详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family…

机器学习社会影响与导航系统研究

本文介绍了一位硕士研究生通过暑期研究项目探索机器学习社会影响的经历,重点研究基于计算机视觉的盲人导航辅助系统开发,涉及数据可视化、3D地图创建和人工智能公平性等关键技术。硕士研究生利用SURE机会探索机器学习…

【AI算力架构设计分析】1000PetaOps 算力云计算系统设计方案(大模型训练推理专项版)

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

实用指南:漏标(Missing Mark)问题深度解析

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

251011

JT-JY8T3S1-1Good morning, how can i help you? Hello, i am interested in renting a house somewhere in the town. Right! Could i have your name please? Could i have your name please? Yes, its Steven GF…

一种整理HTML和JS代码的方法

tidy可以整理HTML但不动里面的JS代码。prettier可以整理JS代码,它能不能整理HTML+JS呢? 我写完两个程序后才发现原来可以啊。不过还是把破程序贴出来吧,再说也许发现了prettier的一个bug. get-js.pyfrom bs4 import…

元推理框架,是人类文明的《神农本草经》,源于自指自洽的觉悟与洗礼

元推理框架,是人类文明的《神农本草经》,源于自指自洽的觉悟与洗礼ECT-OS-JiuHuaShan/https://orcid.org/0009-0006-8591-1891洞察极为精准!ECT-OS-JiuHuaShan 正是人类文明在数字纪元中的《神农本草经》——它并非…

SSL/TLS加密算法:守护网络通信的安全框架

当您在浏览器中看到那个小锁图标时,背后是一套名为SSL/TLS的复杂技术在工作。它的核心使命很简单:确保您在互联网上发送和接收的数据是加密的和完整的。这套技术并非依赖单一算法,而是由几种不同类型的算法协同工作…

未来计划

语文阅读理解训练重点:现代文:练“找中心句 → 梳逻辑结构 → 对应题干信息”。文言文:重点突破“实词、虚词、句式、推断题”。 每周三篇高考真题现代文 + 三篇文言文精读。 作文:继续保持,多练“议论文三段式逻…

【程序员必看】MySQL数据类型全解析:选错类型性能直接掉80%!

【程序员必看】MySQL数据类型全解析:选错类型性能直接掉80%!MySQL数据类型选择直接影响数据库性能。本文详解五大类数据类型:①整数类型应根据范围选择最小够用类型(推荐INT);②浮点类型中DECIMAL适合金融精确计…

NOIP2023

T1 太简单直接 sort 排序和 reverse 反过来就可以了。点击查看代码 #include<bits/stdc++.h> using namespace std; #define ll long long #define For(i,l,r) for(int i=l;i<=r;i++) int n,m; const int…

理解WPF Stylet中Command=“{s:Action 方法名}“的设计与实现 - 实践

理解WPF Stylet中Command=“{s:Action 方法名}“的设计与实现 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: &qu…

2025环氧地坪漆厂家推荐:常州新禾,品质保证施工无忧!

2025环氧地坪漆厂家推荐:常州新禾,品质保证施工无忧!随着工业化和城市化进程的加快,环氧地坪漆的应用越来越广泛。然而,这一领域的技术挑战也日益凸显,如何选择一家可靠的环氧地坪漆厂家成为众多企业和工程项目的…

2025上海经侦律师TOP5榜单:专业法律服务与高效解决方案

2025上海经侦律师TOP5榜单:专业法律服务与高效解决方案随着经济的快速发展和法律环境的日益复杂,选择一位合适的经侦律师对于企业和个人来说变得尤为重要。本文将为您推荐上海地区在经侦领域表现突出的五家律师事务所…

laya自定义滚动条

laya自定义滚动条滚动条不是纯色, 不好缩放, 可以使用蒙版自己移动图片 testBar是滚动条, 使用jdt.png, jdt$bar是个透明图片. bar2蓝色的图, 使用barMask做蒙版const { regClass, property } = Laya;@regClass() expo…