数据导入
本文档引用的文件
- MyEntityNameController.cs
- MyEntityNamesImportModel.cs
- MyEntityNameAppService.cs
- MyEntityNameCreateDto.cs
- MyEntityNameUpdateDto.cs
- MyEntityNameCreateOrUpdateDtoBase.cs
目录
简介
本文档详细说明了POST /api/v{version}/MyPluginName/MyEntityName/Import端点的数据导入功能。该功能支持通过multipart/form-data格式上传Excel文件,解析其中名为“配置”的工作表,并将其映射为MyEntityNamesImportModel数据结构,最终完成数据的校验与持久化操作。整个过程具备事务性保障,确保数据一致性。
Section sources
API端点说明
- 端点路径:
POST /api/v{version}/MyPluginName/MyEntityName/Import - 请求方式:
POST - 内容类型:
multipart/form-data - 认 证要求: 需要授权(
[Authorize]) - 功能描述: 接收上传的Excel文件,解析“配置”工作表,执行数据校验、区分新增与更新记录,并调用相应服务完成数据持久化。
- 成功响应: HTTP 200 OK
- 失败响应: 抛出
UserFriendlyException,返回结构化错误信息。
Diagram sources
数据结构定义
MyEntityNamesImportModel
该模型用于封装从Excel导入的多个MyEntityName记录。
- MyEntityNames:
List<MyEntityNameImportModel>类型,包含所有解析出的行数据。- 在设置该属性时,系统会自动为每行赋值
RowIndex,从第2行开始递增。
- 在设置该属性时,系统会自动为每行赋值
MyEntityNameImportModel
继承自WorkSectionExportModel,表示Excel中的一行数据。
- RowIndex:
int类型,表示该数据在Excel中的行号(从第2行开始)。 - Code:
string类型,对应Excel中的“编号”列。 - Name:
string类型,对应Excel中的“名称”列。 - Remark:
string类型,对应Excel中的“备注”列。
Diagram sources
导入流程详解
数据导入流程遵循严格的顺序和校验规则:
-
文件接收与解析:
- 控制器接收
IFormFile类型的文件。 - 使用
MiniExcelLibs库读取Excel流,并获取所有工作表名称。 - 查找名为“配置”的工作表,使用
MiniExcel.Query<MyEntityNameImportModel>将其反序列化为对象列表。
- 控制器接收
-
空数据校验:
- 若解析结果为空,则抛出“请检查导入的表格”异常。
-
数据预处理与校验:
- 行号自动赋值: 当
MyEntityNames属性被赋值时,其set方法会遍历列表,为每个元素的RowIndex从2开始递增赋值。 - 重复名称校验: 在
ImportAsync服务方法中,首先检查MyEntityNames列表中是否存在名称重复的行。若存在,将汇总所有重复的行号和名称,并抛出包含具体行号的错误信息。 - 空名称校验: 遍历每一 行,若
Name为空或空白,则立即抛出“第X行:MyEntityName名称不能为空”的错误。
- 行号自动赋值: 当
-
区分新增与更新:
- 对于每一行有效数据,通过
_myEntityNameRepository.FindByNameAsync(name)查询数据库。 - 若数据库中已存在同名记录,则将其归类为更新操作,创建
MyEntityNameUpdateDto。 - 若数据库中不存在同名记录,则将其归类为新增操作,创建
MyEntityNameCreateDto。
- 对于每一行有效数据,通过
-
持久化操作:
- 新增操作: 遍历所有
MyEntityNameCreateDto,逐个调用CreateAsync服务。 - 更新操作: 遍历所有
MyEntityNameUpdateDto,逐个调用UpdateAsync服务。 - 事务性回滚: 每个
CreateAsync和UpdateAsync调用都包裹在try-catch中。一旦任一操作失败,将立即捕获异常,构造包含RowIndex的详细错误信息,并抛出UserFriendlyException,终止后续所有操作。
- 新增操作: 遍历所有
Section sources
Excel列与DTO属性映射
Excel文件中的“配置”工作表的列与MyEntityNameImportModel的属性存在直接映射关系:
| Excel列名 | DTO属性名 | 数据类型 | 说明 |
|---|---|---|---|
| 编号 | Code | string | 对应MyEntityNameCreateDto和MyEntityNameUpdateDto中的Code字段。 |
| 名称 | Name | string | 关键字段,用于判断新增/更新,并进行唯一性校验。 |
| 备注 | Remark | string | 对应DTO中的Remark字段。 |
Section sources
错误处理策略
系统实现了多层次的错误处理机制,确保导入过程的健壮性和用户友好性:
-
重复名称检测:
- 在服务层,使用
GroupBy(x => x.Name)对导入数据进行分组。 - 检查每组的
Count()是否大于1。 - 若发现重复,汇总所有重复项的行号和名称,生成如“第 3,5 行:测试名称 名称重复”的提示,并终止导入。
- 在服务层,使用
-
空名称校验:
- 在遍历每一行数据时,检查
Name属性是否为空白。 - 若为空,则立即抛出“第X行:MyEntityName名称不能为空”的错误。
- 在遍历每一行数据时,检查
-
持久化失败回滚:
- 系统虽未使用数据库 事务,但通过顺序执行和立即终止的策略实现了逻辑上的事务性。
- 每次
CreateAsync或UpdateAsync调用都独立捕获异常。 - 一旦失败,立即构造包含
RowIndex的错误信息并抛出,阻止后续所有操作,从而保证数据状态的一致性。
-
通用校验:
CreateAsync和UpdateAsync方法内部调用CheckCreateOrUpdateDtoAsync,对Code、Name、Remark的长度进行校验。
Section sources
- MyEntityNameAppService.cs
- MyEntityNameAppService.cs
- MyEntityNameAppService.cs
- MyEntityNameAppService.cs
客户端调用示例
以下是一个使用curl命令进行文件上传的示例:
curl -X POST "https://your-api-domain/api/v1/MyPluginName/MyEntityName/Import" \
-H "Authorization: Bearer your-jwt-token" \
-H "Content-Type: multipart/form-data" \
-F "file=@/path/to/your/data.xlsx"
注意事项:
file字段的name必须与控制器方法参数名file一致。- Excel文件必须包含一个名为“配置”的工作表。
- “配置”工作表的第二行应为数据,第一行通常为标题(列名)。
Section sources
常见问题与解决方案
| 问题现象 | 可 能原因 | 解决方案 |
|---|---|---|
| 返回“请检查导入的表格” | 1. 上传的文件不是Excel格式。 2. Excel中不存在名为“配置”的工作表。 3. “配置”工作表中没有有效数据。 | 1. 确认文件扩展名为.xlsx或.xls。2. 检查工作表名称是否准确为“配置”,注意中英文和空格。 3. 确保工作表中有至少一行有效数据(非空行)。 |
| 返回“第X行:名称重复” | 在同一个Excel文件中,有多个行的“名称”列内容相同。 | 检查并修改Excel文件,确保所有“名称”列的值在文件内是唯一的。 |
| 返回“第X行:名称不能为空” | 某行数据的“名称”列为空或仅包含空格。 | 检查报错行号对应的行,确保“名称”列填写了有效内容。 |
| 返回“第X行:编号已存在”等业务校验错误 | 该行数据在CreateAsync或UpdateAsync执行时触发了业务规则校验。 | 检查错误信息中的具体描述,修改Excel中的对应数据以满足业务规则(如长度限制)。 |
| 401 Unauthorized | 未提供有效的身份认证令牌。 | 在请求头中添加Authorization: Bearer <your_token>。 |
Section sources