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

调用Persist()前缓存变更已存入数据库问题求助

问题分析

从你的描述和代码来看,核心问题在于在CRCaseClass_RowUpdated事件中直接调用caseContract.Insert(c)会触发Acumatica内置的缓存持久化逻辑,导致变更在你自定义的Persist()方法执行前就被写入数据库,同时缓存被自动清空,使得你重写的Persist()无法按预期处理数据。

Acumatica的缓存机制会在数据操作(如Insert/Update)后,在当前的事务周期内自动跟踪变更,如果你直接操作关联缓存,这些变更会被纳入默认的持久化流程,跳过你自定义的逻辑。

解决方案

我们需要调整数据处理的时机:在Row事件中临时存储变更,直到自定义Persist方法执行时再统一处理缓存和数据库操作。具体步骤如下:

1. 在Graph中添加临时存储集合

首先,在你的Contract Template页面对应的Graph类中,定义一个私有集合来临时保存CaseContract的变更,避免直接操作caseContract缓存:

private List<CaseContract> _pendingCaseContracts = new List<CaseContract>();

2. 修改RowUpdated事件逻辑

在CRCaseClass_RowUpdated事件中,不再直接插入到caseContract缓存,而是将变更记录添加到临时集合中,同时处理新增和更新的场景:

protected void CRCaseClass_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
{
    CRCaseClass newrow = (CRCaseClass)e.Row;
    CRCaseClass oldrow = (CRCaseClass)e.OldRow;
    ContractTemplate currentContract = contracts.Current;
    if (currentContract == null) return;

    CRCaseClassExt newrowExt = PXCache<CRCaseClass>.GetExtension<CRCaseClassExt>(newrow);
    
    // 查找临时集合中是否已有该CaseClass的记录
    var existingRecord = _pendingCaseContracts.FirstOrDefault(cc => 
        cc.ContractID == currentContract.ContractID && 
        cc.CaseClassID == newrow.CaseClassID);

    if (existingRecord != null)
    {
        // 更新已有记录的Active状态
        existingRecord.Active = newrowExt.Check.Value;
    }
    else
    {
        // 添加新的变更记录
        _pendingCaseContracts.Add(new CaseContract
        {
            CaseClassID = newrow.CaseClassID,
            ContractID = currentContract.ContractID,
            Active = newrowExt.Check.Value
        });
    }
}

注意:如果需要处理行删除的场景,可以额外添加CRCaseClass_RowDeleted事件,将对应记录标记为待删除或从临时集合移除。

3. 重写Persist方法,统一处理变更

修改你的Persist()重写方法,先处理临时集合中的记录,同步到caseContract缓存,再执行默认的持久化逻辑:

[PXOverride]
public void Persist()
{
    ContractTemplate currentContract = contracts.Current;
    if (currentContract == null || !_pendingCaseContracts.Any())
    {
        // 无变更时直接执行默认持久化
        Base.Persist();
        return;
    }

    foreach (var pending in _pendingCaseContracts)
    {
        // 查询数据库中是否已有该关联记录
        var existingDbRecord = PXSelect<CaseContract, 
            Where<CaseContract.contractID, Equal<Required<CaseContract.contractID>>,
            And<CaseContract.caseClassID, Equal<Required<CaseContract.caseClassID>>>>>
            .Select(Base, currentContract.ContractID, pending.CaseClassID)
            .FirstOrDefault();

        if (existingDbRecord != null)
        {
            // 更新已有记录
            existingDbRecord.Active = pending.Active;
            caseContract.Update(existingDbRecord);
        }
        else
        {
            // 插入新记录
            caseContract.Insert(pending);
        }
    }

    // 清空临时集合,避免重复处理
    _pendingCaseContracts.Clear();

    // 执行默认持久化逻辑,将缓存变更写入数据库
    Base.Persist();
}
关键说明
  • 临时集合的作用:避免直接操作caseContract缓存,防止Acumatica自动触发提前持久化,确保所有变更都能被自定义Persist方法统一处理。
  • 缓存操作时机:在Persist方法中统一处理缓存的Insert/Update,确保变更在你控制的时机被提交到数据库。
  • 事务一致性:Acumatica的Base.Persist()会处理整个事务,确保所有变更(包括合同模板和CaseContract)要么全部成功,要么全部回滚,保证数据一致性。

内容的提问来源于stack exchange,提问作者Prathyusha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:23:40