Acumatica 为什么我的BLC“保存”操作不保存所有记录,除非它位于缓存插入的最末端?

Acumatica 为什么我的BLC“保存”操作不保存所有记录,除非它位于缓存插入的最末端?,acumatica,Acumatica,我的BLC代码正在解析AuditHistory的“ModifiedFields”字段,因此我有多行单独的“field”和“Value”字段。“ModifiedFields”字段包含空分隔值,因此我的BLC代码使用split函数将这些值放入数组中。这一切都很好。我遇到的问题是通过Graph/Cache“insert”函数保存到Acumatica中的表中。如果我在数组的每次迭代后使用“Actions.PressSave”方法,它不会保存所有记录——实际上会跳过记录。我不知道为什么会这样。如果我将“A

我的BLC代码正在解析AuditHistory的“ModifiedFields”字段,因此我有多行单独的“field”和“Value”字段。“ModifiedFields”字段包含空分隔值,因此我的BLC代码使用split函数将这些值放入数组中。这一切都很好。我遇到的问题是通过Graph/Cache“insert”函数保存到Acumatica中的表中。如果我在数组的每次迭代后使用“Actions.PressSave”方法,它不会保存所有记录——实际上会跳过记录。我不知道为什么会这样。如果我将“Actions.PressSave”方法放在每件事情的最后,我会得到所有记录——但有时它会超时,我假设是因为在某些情况下,在保存之前缓存了大量记录

将PressSave方法放在循环中的任何其他点都会导致丢失记录

以下是我的BLC代码注释:我在几个地方放置了PressSave方法进行测试,但注释掉了-留下最后一个:

public PXAction<AUAuditSetup> CreateAuditRecords;
    [PXProcessButton]
    [PXUIField(DisplayName = "Create Audit Records", MapEnableRights = PXCacheRights.Update, MapViewRights = PXCacheRights.Update)]
    protected virtual IEnumerable createAuditRecords(PXAdapter adapter)
    {

        PXLongOperation.StartOperation(Base, delegate ()
        {

            //Create graph of TAC screen...
            var osdm = PXGraph.CreateInstance<OpenSourceDataMaint>();
            xTACOpenSourceDetail osd;
            int recordID = 1;


            //Get records from AuditHistory
            //PXResultset<AuditHistory> res = PXSelect<AuditHistory>.Select(Base);
            PXResultset<AuditHistory> res = PXSelect<AuditHistory, 
                                            Where<AuditHistory.changeDate, GreaterEqual<Required<AuditHistory.changeDate>>>>.Select(Base, Convert.ToDateTime("01/01/2013"));

            var companyID = Convert.ToString(PX.Common.PXContext.GetSlot<int?>("singleCompanyID"));

            foreach (PXResult<AuditHistory> rec in res)
            {
                var ah = (AuditHistory)rec;
                if (ah != null)
                {
                    string[] fields = ah.ModifiedFields.Split('\0');
                    for (int i = 0; i < fields.GetUpperBound(0); i+=2)
                    {
                        osd = new xTACOpenSourceDetail();
                        osd.OpenSourceName = "AuditHistoryTable";
                        osd.DataID = "1";
                        osd.String01 = Convert.ToString(PX.Common.PXContext.GetSlot<int?>("singleCompanyID"));
                        osd.Number01 = ah.BatchID;
                        osd.Number02 = ah.ChangeID;
                        osd.Number03 = recordID;
                        osd.String02 = ah.ScreenID;
                        osd.String03 = Convert.ToString(ah.UserID);
                        osd.Date01 = ah.ChangeDate;
                        osd.String04 = ah.Operation;
                        osd.String05 = ah.TableName;
                        osd.String06 = ah.CombinedKey;

                        osd.String07 = fields[i];
                        osd.String08 = fields[i + 1];

                        osd.String09 = Convert.ToString(ah.ChangeDate);

                        osdm.OpenSourceDataDetail.Insert(osd);
                        //if (osd != null)
                            //osdm.Actions.PressSave();

                        recordID++;
                    }
                    recordID = 1;
                    //osdm.Actions.PressSave();
                }
                //osdm.Actions.PressSave();
            }
            osdm.Actions.PressSave();
        });

        return adapter.Get();
    }

有什么想法吗?

您可以尝试以下几点:

代替直接实例化osd,替换为:

osd = osdm.OpenSourceDataDetail.Insert();
然后在指定值后,按Save之前,在缓存中使用.Update:

osdm.OpenSourceDataDetail.Update(osd);
然后按Save,清除图形:

osdm.Clear();
重要的是,您的DAC是否在DataID字段上有一个IsKey=true并标记为PXDBIdentity,从而自动分配且唯一

例如:

public abstract class dataID : PX.Data.IBqlField {}

[PXDBIdentity(IsKey = true)]
[PXUIField(Visible = false, Enabled = false)]
public virtual int? DataID {get; set;}

如果更改成功,您可以尝试在For循环后移动。按Save和。Clear

我会检查有问题的DAC的键,并确保键值按预期设置。