You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Acumatica框架SOShipmentEntry扩展删除SOShipLine行报键为空异常如何解决

异常原因
  • 你通过自定义BQL查询返回的SOShipLine实体没有携带完整的主键字段值:Acumatica的缓存删除操作要求操作的实体必须包含所有主键属性的有效值,SOShipLine的主键为CompanyID、ShipmentNbr、LineNbr,如果查询返回的实例缺失任意一个主键值,删除时就会抛出键不能为空的异常
  • 自定义查询返回的实体未关联到当前SOShipmentEntry的Transactions缓存上下文:你直接删除游离的实体实例时,缓存无法定位到对应需要删除的行,也会触发主键校验失败
  • 遍历PXResultset过程中修改缓存会导致枚举上下文异常,可能造成实体字段值丢失,进而触发主键校验错误
解决方案

按照以下步骤调整代码即可解决:

  1. 优先从当前视图的缓存中读取行数据,不要使用自定义查询的游离实例,缓存中的行默认携带完整主键信息
  2. 遍历前将缓存集合转为静态列表,避免遍历过程中修改缓存导致的枚举异常
  3. 删除前先通过主键检索缓存中对应的行,再执行删除操作

修正后的代码示例:

// 先将缓存中的装运行转为静态列表遍历
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 03:57:03