店助工资导入数据未更新问题分析.md
4.26 KB
店助工资导入数据未更新问题分析
问题描述
用户反馈:ID为780436744116897029的记录导入后数据没有改变。
测试结果
导入测试
- 测试文件:
店助工资_20260113143944.xlsx - 导入结果: 成功 36 条,失败 0 条,跳过 0 条
- 状态码: 200
- 接口响应: 正常
数据库记录状态
- 记录ID:
780436744116897029 - 员工姓名: 刘雨佳
- 门店名称: 绿纤双流店
- 锁定状态:
F_IsLocked = 0(未锁定) - 确认状态:
F_EmployeeConfirmStatus = 0(未确认) - 更新时间:
2026-01-12T16:38:42.000Z(导入测试时间为2026-01-13)
问题分析
代码逻辑
从 LqAssistantSalaryService.cs 的导入代码来看:
// 第1126行
var entity = existing ?? new LqAssistantSalaryStatisticsEntity { ... };
// 如果existing不为null,entity和existing指向同一个对象
// 然后修改entity的属性值
entity.StoreName = storeName;
entity.EmployeeName = employeeName;
// ... 其他字段赋值
// 第1233行
entity.UpdateTime = DateTime.Now;
// 第1234行
if (existing != null) recordsToUpdate.Add(entity);
SqlSugar Updateable 行为
SqlSugar的Updateable方法默认只更新有变化的字段。如果实体对象的所有字段值与数据库中的值完全相同,SqlSugar可能不会执行任何SQL更新操作。
可能的原因
- 数据完全相同: Excel中的所有字段值与数据库中的值完全相同,导致SqlSugar认为没有变化,不执行更新
- UpdateTime未生效: 虽然代码设置了
entity.UpdateTime = DateTime.Now,但如果其他所有字段都相同,SqlSugar可能仍然不执行更新(这是一个潜在的SqlSugar行为问题) - 实体对象引用问题: 由于
entity = existing,实体对象来自数据库查询,SqlSugar可能使用原始值进行比较
解决方案
方案1:强制更新所有字段(推荐)
使用UpdateColumns明确指定要更新的字段,确保所有字段都被更新:
if (recordsToUpdate.Any())
{
await _db.Updateable(recordsToUpdate)
.UpdateColumns(it => new
{
it.StoreName,
it.EmployeeName,
it.Position,
it.StoreTotalPerformance,
it.StoreBillingPerformance,
// ... 列出所有需要更新的字段
it.UpdateTime
})
.ExecuteCommandAsync();
}
方案2:使用IgnoreColumns排除不需要更新的字段
使用IgnoreColumns排除CreateTime等不需要更新的字段,但更新其他所有字段:
if (recordsToUpdate.Any())
{
await _db.Updateable(recordsToUpdate)
.IgnoreColumns(x => x.CreateTime)
.IgnoreColumns(x => x.CreateUser)
.ExecuteCommandAsync();
}
方案3:创建新实体对象(不推荐,性能较差)
不使用existing对象,而是创建新的实体对象:
if (existing != null)
{
entity = new LqAssistantSalaryStatisticsEntity
{
Id = existing.Id,
StoreId = existing.StoreId,
EmployeeId = existing.EmployeeId,
StatisticsMonth = existing.StatisticsMonth,
// ... 复制所有字段
};
}
建议
- 立即修复: 使用方案1(UpdateColumns)或方案2(IgnoreColumns)确保导入时所有字段都被更新
- 验证数据: 检查Excel中的数据是否真的与数据库中的数据不同
- 日志记录: 添加日志记录,记录每次导入时实际更新的记录数和字段变化
- 统一处理: 检查其他工资服务的导入代码,确保它们也使用相同的更新策略
相关代码位置
- 文件:
netcore/src/Modularity/Extend/NCC.Extend/LqAssistantSalaryService.cs - 方法:
ImportSalaryFromExcel - 关键代码行: 第1126行(entity赋值)、第1233行(UpdateTime设置)、第1251行(批量更新)
参考实现
可以参考LqSalaryExtraCalculationService.cs中的实现,它使用了UpdateColumns来明确指定要更新的字段:
await _db.Updateable(uniqueEntitiesToUpdate)
.UpdateColumns(it => new
{
it.BaseRewardPerformance,
it.CooperationRewardPerformance,
// ... 明确列出要更新的字段
})
.ExecuteCommandAsync();