我正在尝试创建一个每天运行的流程,该流程将从另一个数据库中导入记录作为“库存物品”。为此,我需要创建InventoryItemMaint图的扩展(给我自定义操作),以及InventoryItem DAC的扩展(给我自定义字段)。我试图遵循T-300手册中明确规定的准则进行操作。
这是我的InventoryItemMaint扩展的代码:
namespace PX.Objects.IN
{
public class InventoryItemMaint_Extension:PXGraphExtension<InventoryItemMaint>
{
public PXAction<PX.Objects.IN.InventoryItem> DailyOnixImport;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Daily Onix Import")]
protected void dailyOnixImport()
{
var invItemMaintExtInstance = Base.GetExtension<InventoryItemMaint_Extension>();
string todaysDate = DateTime.Today.ToString("MM/dd/yyyy");
foreach (STOnixItem currentOnixItem in PXSelect<STOnixItem,
Where<STOnixItem.addedDate, Equal<Required<STOnixItem.addedDate>>>>
.Select(this.Base, todaysDate))
{
InventoryItem currentInventoryItem = invItemMaintExtInstance.Base.Item.Current;
PXCache inventoryItemCache = invItemMaintExtInstance.Base.Item.Cache;
InventoryItemExt inventoryItemExtension = inventoryItemCache.GetExtension<InventoryItemExt>(currentInventoryItem);
inventoryItemCache.Clear();
currentInventoryItem.InventoryCD = currentOnixItem.ISBN13;
currentInventoryItem.Descr = currentOnixItem.Title;
currentInventoryItem.ItemClassID = currentOnixItem.ItemClass;
currentInventoryItem.RecPrice = decimal.Parse(currentOnixItem.MSRP);
currentInventoryItem.BasePrice = decimal.Parse(currentOnixItem.DefaultPrice);
currentInventoryItem.BaseItemWeight = decimal.Parse(currentOnixItem.Weight);
currentInventoryItem.WeightUOM = "POUND";
currentInventoryItem.ImageUrl = currentOnixItem.ImageLink;
//Assigning to the custom DAC Extension
inventoryItemExtension.UsrFromOnixFile = currentOnixItem.FromFile;
inventoryItemCache.Update(currentInventoryItem);
Base.Actions.PressSave();
}
}
}
}
我目前收到一条错误消息:
错误:另一个进程已更新'InventoryItem'记录。您的 更改将丢失。
这是错误跟踪文本:
9/20/2018 3:26:05 PM错误:错误:另一个进程添加了 “ InventoryItem”记录。您的更改将丢失。
位于PX.Data.PXCache
1.PersistInserted(Object row) at PX.Data.PXCache
1.Persist(位于PXDBOperation操作) PX.Data.PXGraph.Persist(类型cacheType,PXDBOperation操作)
在PX.Data.PXGraph.Persist()在 PX.Objects.IN.InventoryItemMaint.Persist()在 PX.Data.PXSave1.d__2.MoveNext() at PX.Data.PXAction
1.d__31.MoveNext()在 PX.Data.PXAction1.d__31.MoveNext() at PX.Data.PXActionCollection.PressSave(PXAction caller) at PX.Objects.IN.InventoryItemMaint_Extension.dailyOnixImport() at PX.Data.PXAction
1。<> c__DisplayClass3_0。<。ctor> b__0(PXAdapter适配器) 在PX.Data.PXAction1.a(PXAdapter A_0) at PX.Data.PXAction
1.d__31.MoveNext()在 PX.Data.PXAction`1.d__31.MoveNext()在 PX.Web.UI.PXBaseDataSource.tryExecutePendingCommand(String viewName, String [] sortcolumns,Boolean []降序,Object []搜索, Object []参数,PXFilterRow []过滤器,DataSourceSelectArguments 参数,Boolean&closeWindowRequired,Int32&adapterStartRow, Int32&adapterTotalRows)位于 PX.Web.UI.PXBaseDataSource.ExecuteSelect(String viewName, DataSourceSelectArguments参数,PXDSSelectArguments pxarguments)
我已经在StackOverflow和其他地方进行了很多搜索,但是还没有找到似乎完全可以解决我的问题的答案。我所做的调整导致了其他错误,例如我现在所获取内容的变化(添加了另一个过程而更新了另一个过程)和MoveNext错误。
如果有人能够帮助我,我将非常感激。
答案 0 :(得分:0)
代码中似乎存在逻辑缺陷。您正在循环更新同一当前对象。这毫无用处,因为它将始终用循环返回的最后一项覆盖。如果您不小心,则循环调用“保存”操作也会导致错误。
正如我在评论中提到的,清除缓存似乎是错误的。您想将当前数据保留在那里。当您调用clear时,您将使图形的主要文档失效,这将导致错误。
与InventoryCD之类的键紧密相关的更改字段可能会导致文档被清除和无效。如果您必须考虑插入新记录而不是更新当前记录来修改关键字段。
我建议您进行其他更改。
代码:
// Consider replacing the default namespace to avoid conflicts
namespace MyNamespace
{
public class InventoryItemMaint_Extension:PXGraphExtension<InventoryItemMaint>
{
public PXAction<PX.Objects.IN.InventoryItem> DailyOnixImport;
// '(CommitChanges = true)' is not necessary
[PXButton]
[PXUIField(DisplayName = "Daily Onix Import")]
protected void dailyOnixImport()
{
InventoryItemMaint_Extension invItemMaintExtInstance = Base.GetExtension<InventoryItemMaint_Extension>();
string todaysDate = DateTime.Today.ToString("MM/dd/yyyy");
// You need to rethink that 'foreach' logic
STOnixItem currentOnixItem in PXSelect<STOnixItem,
Where<STOnixItem.addedDate, Equal<Required<STOnixItem.addedDate>>>>.Select(Base, todaysDate);
// You can access Base directly, no need to fetch it from the extension
InventoryItem currentInventoryItem = Base.Item.Current;
// Consider using more null check
if (currentOnixItem != null && currentInventoryItem != null)
{
// Consider using similar names for similar variables
InventoryItemExt currentInventoryItemExt = currentInventoryItem.GetExtension<InventoryItemExt>();
// Avoid setting key related fields like InventoryCD when updating
currentInventoryItem.Descr = currentOnixItem.Title;
currentInventoryItem.ItemClassID = currentOnixItem.ItemClass;
currentInventoryItem.RecPrice = decimal.Parse(currentOnixItem.MSRP);
currentInventoryItem.BasePrice = decimal.Parse(currentOnixItem.DefaultPrice);
currentInventoryItem.BaseItemWeight = decimal.Parse(currentOnixItem.Weight);
currentInventoryItem.WeightUOM = "POUND";
currentInventoryItem.ImageUrl = currentOnixItem.ImageLink;
currentInventoryItemExt.UsrFromOnixFile = currentOnixItem.FromFile;
// You fetched the item from the DataView
// you can update it in the DataView too.
Base.Item.Update(currentInventoryItem);
// Is it really needed to save here?
// This coupled with cache clearing and the loop updating
// the same record triggers the error in your question.
Base.Actions.PressSave();
}
}
}
}
答案 1 :(得分:0)
伙计们,
当我们尝试更新DAC中的复杂字段之一时,我在EmployeeMaint
中遇到了相同的异常。
baseAction()也会引发此异常。 我遵循了您的建议@HuguesBeauséjour,发现原因可能是:
意味着,缓存已脏。 因此,要解决我的问题,我只需要清除引发异常的对象的缓存。 在我的情况下,例外是:
Update employee class error - Another process has added the 'VendorPaymentMethodDetail' record. Your changes will be lost
所以我需要清除VendorPaymentMethodDetail
的缓存:
Base.Caches<VendorPaymentMethodDetail>().Clear();
在清除高速缓存后,需要在代码期间从高速缓存中读取数据时,请小心清除高速缓存。在这种情况下,您需要在清理之前从缓存中复制对象,然后再使用此副本。
希望对某人有帮助。
答案 2 :(得分:0)
当您从不同缓存中的同一表中进行选择时,可能会发生这种情况,其中一个用于选择,另一个用于插入。例如:
我们有一个观点:
public PXSelect<MPEmployeeWorkSchedule, Where<MPEmployeeWorkSchedule.employeeID, Equal<Current<MPEmployeeTermination.employeeID>>>> EmployeeWorkSchedule;
并且在事件中我们有代码段: 我们使用与上面的视图相同的DAC,然后将其插入视图:
EmployeeWorkSchedule.Cache.Insert(workSchedule);
然后Persist()
引发异常。
我希望这会有所帮助。
答案 3 :(得分:0)
想分享另一种查找相同错误消息的方法。就我而言,问题出在数据库结构上。 为了修复错误消息,我执行了以下步骤:
结果,我的错误消息消失了。