为什么我的BLC“保存”操作不保存所有记录,除非它在缓存插入的末尾?

时间:2019-09-16 14:38:15

标签: acumatica

我有一些BLC代码正在解析AuditHistory的“ ModifiedFields”字段,因此我有多行带有单独的“ Field”和“ Value”字段。 'ModifiedFields'字段包含空分隔的值,因此我的BLC C#代码使用split函数将它们放入数组中。这一切都很好。我遇到的问题是通过“图形/缓存”“插入”功能保存到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();
    }

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

您可以尝试的几件事:

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

osd = osdm.OpenSourceDataDetail.Insert();

,然后在分配值之后并在PressSave()之前,在缓存上使用.Update:

osdm.OpenSourceDataDetail.Update(osd);

,然后在PressSave()之后,清除图形:

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循环之后移动.PressSave()和.Clear()。