diff --git a/docs/content/user-guide/zh/getting-started/quick-start.md b/docs/content/user-guide/zh/getting-started/quick-start.md
index 8c6ddc51..d43e49e2 100644
--- a/docs/content/user-guide/zh/getting-started/quick-start.md
+++ b/docs/content/user-guide/zh/getting-started/quick-start.md
@@ -31,7 +31,7 @@ docker run -d --name myrabbitmq -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAU
### 安装 Cli 工具
-- [仓库地址](https://github.com/WangJunZzz/Lion.AbpPro.Cli)
+- 安装 Cli
```bash
dotnet tool install Lion.AbpPro.Cli -g
@@ -39,24 +39,30 @@ dotnet tool install Lion.AbpPro.Cli -g
### 生成项目
-**提供了三个模板生成**
-
- 生成源码版本
```bash
-lion.abp new abp-vnext-pro -c 公司名称 -p 项目名称 -v 版本号(默认LastRelease)
+lion.abp new -t pro -c 公司名称 -p 项目名称 -v 版本(默认LastRelease) -o 默认当前控制台执行目录
+```
+
+- nuget 包形式的网关基础版本
+ - abp 自带的所有模块,pro 的通知模块,数据字典模块 以及 ocelot 网关。
+
+```bash
+lion.abp new -t pro.all -c 公司名称 -p 项目名称 -v 版本(默认LastRelease) -o 默认当前控制台执行目录
```
-- nuget 包形式的基础版本,包括 abp 自带的所有模块,已经 pro 的通知模块,数据字典模块 以及 ocelot 网关
+- nuget 包形式的基础版本
+ - abp 自带的所有模块,pro 的通知模块,数据字典模块 无 ocelot 网关
```bash
-lion.abp new abp-vnext-pro-basic -c 公司名称 -p 项目名称 -v 版本(默认LastRelease)
+lion.abp new -t pro.simplify -c 公司名称 -p 项目名称 -v 版本(默认LastRelease) -o 默认当前控制台执行目录
```
-- nuget 包形式的基础版本,包括 abp 自带的所有模块,已经 pro 的通知模块,数据字典模块 无 ocelot 网关
+- 模块
```bash
-lion.abp new abp-vnext-pro-basic-no-ocelot -c 公司名称 -p 项目名称 -v 版本(默认LastRelease)
+lion.abp new -t pro.module -c 公司名称 -p 项目名称 -v 版本(默认LastRelease) -o 默认当前控制台执行目录
```
### 后端
diff --git a/docs/content/user-guide/zh/infrastructure/batch.md b/docs/content/user-guide/zh/infrastructure/batch.md
new file mode 100644
index 00000000..d02d23f3
--- /dev/null
+++ b/docs/content/user-guide/zh/infrastructure/batch.md
@@ -0,0 +1,176 @@
+# 批量操作
+
+EFCore7.0 之后,提供了批量更新和批量删除,但是不提供批量新增,
+[微软 EFCore 批量操作文档](https://learn.microsoft.com/zh-cn/ef/core/saving/execute-insert-update-delete)
+
+## 安装
+
+- 添加以下 NuGet 包到你的项目
+ - Lion.AbpPro.EntityFrameworkCore.Mysql
+- 添加 [DependsOn(typeof(LionAbpProEntityFrameworkCoreMysqlModule))] 到你的项目模块类.
+
+## 原理
+
+- 通过 MySqlBulkCopy 来实现批量新增[官方文档](https://mysqlconnector.net/api/mysqlconnector/mysqlbulkcopytype/)
+- 实现 Abp 批量操作接口 IEfCoreBulkOperationProvider
+
+```csharp
+public class EfCoreBulkOperationProvider : IEfCoreBulkOperationProvider, ITransientDependency
+{
+ ///
+ /// 批量新增
+ ///
+ ///
+ ///
+ /// - mysql启用:SET GLOBAL local_infile = true;
+ ///
+ ///
+ /// - 数据库连接字符串需要加上:AllowLoadLocalInfile=true
+ ///
+ /// - abp的审计字段需要手动赋值,比如创建人,创建时间,或者使用AuditPropertySetter
+ ///
+ /// - 只支持单表,比如有一个Blog表和Post表一对多关系,需要调用两次 InsertManyAsync
+ ///
+ ///
+ public virtual async Task InsertManyAsync(IEfCoreRepository repository, IEnumerable entities, bool autoSave, CancellationToken cancellationToken)
+ where TDbContext : IEfCoreDbContext where TEntity : class, IEntity
+ {
+ var dbContext = await repository.GetDbContextAsync();
+ var dbTransaction = dbContext.Database.CurrentTransaction?.GetDbTransaction();
+ await dbContext.BulkInsertAsync(entities, dbTransaction as MySqlTransaction, cancellationToken);
+ if (autoSave)
+ {
+ await dbContext.SaveChangesAsync(cancellationToken);
+ }
+ }
+}
+```
+
+## 示例
+
+```csharp
+namespace Lion.AbpPro.EntityFrameworkCore.Tests.Services;
+
+public class BlogAppService : ApplicationService
+{
+ private readonly IBlogRepository _blogRepository;
+ private readonly IRepository _postRepository;
+ private readonly IRepository _commentRepository;
+ private readonly IdentityRoleManager _identityRoleManager;
+
+ public BlogAppService(IBlogRepository blogRepository, IdentityRoleManager identityRoleManager, IRepository postRepository, IRepository commentRepository)
+ {
+ _blogRepository = blogRepository;
+ _identityRoleManager = identityRoleManager;
+ _postRepository = postRepository;
+ _commentRepository = commentRepository;
+ }
+
+
+ ///
+ /// 批量插入10000条数据
+ ///
+ public async Task CreateAsync(int qty = 10000)
+ {
+ // mock 数据
+ var list = GenFu.GenFu.ListOf(qty);
+ var stopwatch = new Stopwatch();
+ stopwatch.Start();
+ await _blogRepository.InsertManyAsync(list);
+ stopwatch.Stop();
+ Logger.LogInformation($"批量插入{list.Count}条,耗时(单位:毫秒):{stopwatch.ElapsedMilliseconds}");
+ }
+
+ ///
+ /// 批量插入10000条数据
+ ///
+ public async Task CreateAllAsync(int qty = 10000)
+ {
+ // mock 数据
+ var blogs = GenFu.GenFu.ListOf(qty);
+ var posts = new List();
+ var comments = new List();
+ // blog和post一对多,post和comment一对多
+ // 有主外键关系,所以循环mock数据
+ foreach (var blog in blogs)
+ {
+ posts.Add(new Post(GuidGenerator.Create(), blog.Id, "name"));
+ }
+
+
+ foreach (var post in posts)
+ {
+ comments.Add(new Comment(GuidGenerator.Create(), 1, post.Id, "content"));
+ }
+
+ var stopwatch = new Stopwatch();
+ stopwatch.Start();
+ // 需要执行三次,不会因为ef有定义关系而一次性插入posts和comments
+ await _blogRepository.InsertManyAsync(blogs);
+ await _postRepository.InsertManyAsync(posts);
+ await _commentRepository.InsertManyAsync(comments);
+ stopwatch.Stop();
+ Logger.LogInformation($"批量插入blogs:{blogs.Count},posts:{posts.Count},comments:{comments.Count}条,耗时(单位:毫秒):{stopwatch.ElapsedMilliseconds}");
+ }
+
+ ///
+ /// 批量插入10000条数据,并且测试事务是否和其它业务逻辑保持一致
+ /// 测试结果:在一个事务内
+ ///
+ public async Task CreateTransactionAsync(int qty = 10)
+ {
+ var list = GenFu.GenFu.ListOf(qty);
+ var stopwatch = new Stopwatch();
+ stopwatch.Start();
+ await _blogRepository.InsertManyAsync(list);
+ stopwatch.Stop();
+ Logger.LogInformation($"批量插入{list.Count}条,耗时(单位:毫秒):{stopwatch.ElapsedMilliseconds}");
+ await _identityRoleManager.CreateAsync(new IdentityRole(GuidGenerator.Create(), GuidGenerator.Create().ToString()));
+ throw new UserFriendlyException("test");
+ }
+
+ ///
+ /// 批量更新
+ ///
+ ///
+ public async Task BatchUpdateAsync(int qty = 10000)
+ {
+ using (var uow = UnitOfWorkManager.Begin(new AbpUnitOfWorkOptions(true), true))
+ {
+ var list = GenFu.GenFu.ListOf(qty);
+ await _blogRepository.InsertManyAsync(list);
+ await uow.CompleteAsync();
+ }
+
+ var stopwatch = new Stopwatch();
+ stopwatch.Start();
+ var dbSet = await _blogRepository.GetDbSetAsync();
+ await dbSet.ExecuteUpdateAsync(setters => setters
+ .SetProperty(x => x.IsDeleted, x => true)
+ .SetProperty(x => x.Name, x => "test"));
+ stopwatch.Stop();
+ Logger.LogInformation($"批量更新{qty}条,耗时(单位:毫秒):{stopwatch.ElapsedMilliseconds}");
+ }
+
+ ///
+ /// 批量删除
+ ///
+ ///
+ public async Task BatchDeleteAsync(int qty = 10000)
+ {
+ using (var uow = UnitOfWorkManager.Begin(new AbpUnitOfWorkOptions(true), true))
+ {
+ var list = GenFu.GenFu.ListOf(qty);
+ await _blogRepository.InsertManyAsync(list);
+ await uow.CompleteAsync();
+ }
+
+ var stopwatch = new Stopwatch();
+ stopwatch.Start();
+ var dbSet = await _blogRepository.GetDbSetAsync();
+ await dbSet.ExecuteDeleteAsync();
+ stopwatch.Stop();
+ Logger.LogInformation($"批量删除{qty}条,耗时(单位:毫秒):{stopwatch.ElapsedMilliseconds}");
+ }
+}
+```
diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml
index aabdd9d3..bc4ee404 100644
--- a/docs/mkdocs.yml
+++ b/docs/mkdocs.yml
@@ -70,28 +70,31 @@ markdown_extensions:
nav:
- Home: index.md
- - 文档(中文):
- - 入门:
- - 快速开始: user-guide/zh/getting-started/quick-start.md
- - 介绍: user-guide/zh/getting-started/introduction.md
- - 贡献: user-guide/zh/getting-started/contributing.md
- - 基础设施:
- - 配置: user-guide/zh/infrastructure/config.md
- - 前端: user-guide/zh/infrastructure/frontend.md
- - FreeSql: user-guide/zh/infrastructure/freesql.md
- - 分布式事件: user-guide/zh/infrastructure/cap.md
- - 应用模块:
- - 基础模块: user-guide/zh/modules/basic.md
- - 设置(Setting): user-guide/zh/modules/setting.md
- - 数据字典: user-guide/zh/modules/dic.md
- - 文件管理: user-guide/zh/modules/file.md
- - 实时通信: user-guide/zh/modules/signalr.md
- - 扩展:
- - 统一返回值格式: user-guide/zh/extension/统一返回值格式.md
- - Magicodes.IE: user-guide/zh/extension/MagicodesIE.md
- - 部署:
- - Docker: user-guide/zh/deploy/docker.md
- - Github自动化部署: user-guide/zh/deploy/github.md
+ - 入门:
+ - 快速开始: user-guide/zh/getting-started/quick-start.md
+ - 介绍: user-guide/zh/getting-started/introduction.md
+ - 贡献: user-guide/zh/getting-started/contributing.md
+ - 基础设施:
+ - 配置: user-guide/zh/infrastructure/config.md
+ - 前端: user-guide/zh/infrastructure/frontend.md
+ - FreeSql: user-guide/zh/infrastructure/freesql.md
+ - 分布式事件: user-guide/zh/infrastructure/cap.md
+ - 批量操作: user-guide/zh/infrastructure/batch.md
+ - 应用模块:
+ - 基础模块: user-guide/zh/modules/basic.md
+ - 设置(Setting): user-guide/zh/modules/setting.md
+ - 数据字典: user-guide/zh/modules/dic.md
+ - 文件管理: user-guide/zh/modules/file.md
+ - 实时通信: user-guide/zh/modules/signalr.md
+ - 扩展:
+ - 统一返回值格式: user-guide/zh/extension/统一返回值格式.md
+ - Magicodes.IE: user-guide/zh/extension/MagicodesIE.md
+ - 常见问题:
+ - 编译: user-guide/zh/problem/problem.md
+ - EFCore: user-guide/zh/problem/ef.md
+ - 部署:
+ - Docker: user-guide/zh/deploy/docker.md
+ - Github自动化部署: user-guide/zh/deploy/github.md
- 常见问题:
- 编译: user-guide/zh/problem/problem.md
- EFCore: user-guide/zh/problem/ef.md