店助工资导入数据未更新问题分析.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更新操作。

可能的原因

  1. 数据完全相同: Excel中的所有字段值与数据库中的值完全相同,导致SqlSugar认为没有变化,不执行更新
  2. UpdateTime未生效: 虽然代码设置了entity.UpdateTime = DateTime.Now,但如果其他所有字段都相同,SqlSugar可能仍然不执行更新(这是一个潜在的SqlSugar行为问题)
  3. 实体对象引用问题: 由于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. 立即修复: 使用方案1(UpdateColumns)或方案2(IgnoreColumns)确保导入时所有字段都被更新
  2. 验证数据: 检查Excel中的数据是否真的与数据库中的数据不同
  3. 日志记录: 添加日志记录,记录每次导入时实际更新的记录数和字段变化
  4. 统一处理: 检查其他工资服务的导入代码,确保它们也使用相同的更新策略

相关代码位置

  • 文件: 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();