# 储扣表 F_ItemCategory 字段为空问题梳理 ## 问题描述 储扣表(lq_kd_deductinfo)中的 `F_ItemCategory` 字段有时候是空的。 ## 数据库统计 - 总有效记录数:1865 - 有分类字段的记录数:1863 - 分类字段为空的记录数:2 ## 问题分析 ### 1. 创建开单时的逻辑(第910行) ```csharp ItemCategory = await _db.Queryable() .Where(x => x.Id == item.ItemId) .Select(x => x.Qt2) .FirstAsync(), ``` - 使用 `item.ItemId` 查询品项分类 - 如果 `item.ItemId` 为空或无效,查询会返回 null ### 2. 更新开单时的逻辑(第1257行) ```csharp ItemCategory = await _db.Queryable() .Where(x => x.Id == item.DeductId) // ❌ 错误:应该使用 item.ItemId .Select(x => x.Qt2) .FirstAsync() ``` - **问题**:使用了 `item.DeductId` 而不是 `item.ItemId` - `DeductId` 是品项明细表(lq_kd_pxmx)的ID,不是项目资料表(lq_xmzl)的ID - 这会导致查询不到结果,返回 null ### 3. 字段说明 - **DeductId**:扣减品项关联ID,对应 `lq_kd_pxmx.F_Id`(品项明细表的主键) - **ItemId**:品项id,对应 `lq_xmzl.F_Id`(项目资料表的主键) - **ItemCategory**:品项分类,应该从 `lq_xmzl.qt2` 获取 ### 4. 导致空值的原因 1. **更新开单时使用了错误的字段**:使用 `item.DeductId` 而不是 `item.ItemId` 2. **查询不到结果**:如果 `item.ItemId` 为空或无效,`FirstAsync()` 会返回 null 3. **品项不存在或无效**:如果品项在 `lq_xmzl` 表中不存在或无效,查询也会返回 null ## 解决方案 ### ✅ 方案1:修复更新开单时的逻辑(已修复) 将第1257行的 `item.DeductId` 改为 `item.ItemId`,与创建开单时的逻辑保持一致。 **修复代码**: ```csharp // 修复前(错误) ItemCategory = await _db.Queryable() .Where(x => x.Id == item.DeductId) // ❌ 错误 .Select(x => x.Qt2) .FirstAsync() // 修复后(正确) ItemCategory = await _db.Queryable() .Where(x => x.Id == item.ItemId) // ✅ 正确 .Select(x => x.Qt2) .FirstAsync() ``` ### ✅ 方案2:修复历史数据(已提供SQL脚本) 对于已经存在的空值记录,执行 `sql/修复储扣表ItemCategory字段为空的数据.sql` 脚本修复。 ### 方案3:增加容错处理(可选) 在查询时增加容错处理,如果查询不到结果,尝试从其他途径获取分类。 ## 验证 从数据库查询结果看: - F_ItemId = '76',对应的 lq_xmzl 表中 qt2 = '科美'(存在且有效) - F_ItemId = '100024',对应的 lq_xmzl 表中 qt2 = '科美'(存在且有效) 说明这些记录的 `ItemId` 是有效的,问题应该是在更新开单时使用了错误的字段。