Acumatica框架SOShipmentEntry扩展删除SOShipLine行报键为空异常如何解决
异常原因
- 你通过自定义BQL查询返回的
SOShipLine实体没有携带完整的主键字段值:Acumatica的缓存删除操作要求操作的实体必须包含所有主键属性的有效值,SOShipLine的主键为CompanyID、ShipmentNbr、LineNbr,如果查询返回的实例缺失任意一个主键值,删除时就会抛出键不能为空的异常 - 自定义查询返回的实体未关联到当前
SOShipmentEntry的Transactions缓存上下文:你直接删除游离的实体实例时,缓存无法定位到对应需要删除的行,也会触发主键校验失败 - 遍历
PXResultset过程中修改缓存会导致枚举上下文异常,可能造成实体字段值丢失,进而触发主键校验错误
解决方案
按照以下步骤调整代码即可解决:
- 优先从当前视图的缓存中读取行数据,不要使用自定义查询的游离实例,缓存中的行默认携带完整主键信息
- 遍历前将缓存集合转为静态列表,避免遍历过程中修改缓存导致的枚举异常
- 删除前先通过主键检索缓存中对应的行,再执行删除操作
修正后的代码示例:
// 先将缓存中的装运行转为静态列表遍历 List<SOShipLine> cachedShipLines = Base.Transactions.Cache.Cached<SOShipLine>() .Where(line => line.ShipmentNbr == shipment.ShipmentNbr) .ToList(); List<Linelevel> lineLevels = osr.Transaction.Transaction.Order.LineLevel; foreach (SOShipLine shipLine in cachedShipLines) { Linelevel lineLevel = lineLevels.Find(lineNbr => lineNbr.POLineNum == shipLine.LineNbr); if (lineLevel != null) { shipLine.ShippedQty = lineLevel.PickedQuantity; Base.Transactions.Cache.Update(shipLine); } else { // 确认主键都有值后,删除缓存中对应的行 if (shipLine.ShipmentNbr != null && shipLine.LineNbr != null) { var lineToDelete = Base.Transactions.Search<SOShipLine.shipmentNbr, SOShipLine.lineNbr>(shipLine.ShipmentNbr, shipLine.LineNbr); if (lineToDelete != null) { Base.Transactions.Cache.Delete(lineToDelete); } } } }
内容的提问来源于stack exchange,提问作者Jorge Peruyero
相关产品推荐
相关产品推荐

