Acumatica从2020 R2升级至2022 R2后类型转换报错求助
问题分析
错误Unable to cast object of type 'APDocumentResult' to type 'PX.Data.PXResult1[PX.Objects.AP.APDocumentEnq+APDocumentResult]'的核心原因是:Acumatica 2022 R2版本中,APDocumentEnq的Documents视图返回的直接是APDocumentResult实体对象,而非2020 R2版本中被PXResult`包装的对象。你的定制代码仍按旧版本的返回类型做强制转换,导致类型不匹配。
解决方案
修改documents()方法中的遍历逻辑,直接处理APDocumentResult对象,而非PXResult<APDocumentResult>:
修改后的代码
public PXSelectOrderBy<APDocumentEnq.APDocumentResult, OrderBy<Asc<APDocumentEnq.APDocumentResult.docDate>>> Documents; protected virtual IEnumerable documents() { decimal decCurrRunningBal = 0; decimal decRunningBal = 0; Dictionary<string, decimal> curydict = new Dictionary<string, decimal>(); BqlCommand query = Base.Documents.View.BqlSelect; PXView view = new PXView(Base, true, query, Base.Documents.View.BqlDelegate); int intStartRow = PXView.StartRow; int intTotalRows = 0; List<Object> list = view.Select(PXView.Currents, PXView.Parameters, PXView.Searches, PXView.SortColumns, PXView.Descendings, PXView.Filters, ref intStartRow, PXView.MaximumRows, ref intTotalRows); PXView.StartRow = 0; // 直接遍历APDocumentResult对象,不再用PXResult包装 foreach (APDocumentEnq.APDocumentResult row in list) { if (row == null) continue; APRegisterExt registerExt = this.Base.Documents.Cache.GetExtension<APRegisterExt>(row); //KES Running Balance decRunningBal += row.OrigDocAmt ?? 0; //Foreign Running Balance if (row.CuryID != "KSHS") { if (curydict.ContainsKey(row.CuryID)) { curydict[row.CuryID] += row.CuryOrigDocAmt ?? 0; decCurrRunningBal = curydict[row.CuryID]; } else { curydict[row.CuryID] = row.CuryOrigDocAmt ?? 0; decCurrRunningBal = curydict[row.CuryID]; } } registerExt.UsrCurrencyRbal = decCurrRunningBal; registerExt.UsrVenderbal = decRunningBal; } return list; } //CODE FOR DISPLAYING DOCUMENT TAX protected void APDocumentResult_RowSelected(PXCache cache, PXRowSelectedEventArgs e) { APDocumentEnq.APDocumentResult row = (APDocumentEnq.APDocumentResult)e.Row; if(row == null) return; APRegisterExt extObj = cache.GetExtension<APRegisterExt>(row); APInvoice invoiceObj = PXSelect<APInvoice, Where<APInvoice.refNbr, Equal<Required<APInvoice.refNbr>>, And<APInvoice.docType, Equal<Required<APInvoice.docType>>>>>.Select(this.Base, row.RefNbr, row.DocType); if(invoiceObj != null) { extObj.UsrTaxAmt = invoiceObj.CuryTaxTotal; if(invoiceObj.CuryTaxTotal> 0) extObj.UsrTwopercent = (invoiceObj.CuryTaxTotal * 0.125m); } }
关键修改点
- 将
foreach (PXResult<APDocumentEnq.APDocumentResult> item in list)改为foreach (APDocumentEnq.APDocumentResult row in list),直接处理实体对象 - 移除
item.GetItem<APDocumentEnq.APDocumentResult>()的调用,因为遍历变量本身就是目标实体 - 添加
if (row == null) continue;空值检查,避免潜在的空引用异常
额外注意事项
- 确认
APRegisterExt是针对APDocumentResult的扩展字段,而非APRegister(如果是后者,需要调整缓存获取扩展的方式) - 测试升级后的其他定制逻辑,因为Acumatica跨版本升级可能会有多处BQL或视图返回结构的变更
内容的提问来源于stack exchange,提问作者DevFuture
相关产品推荐
相关产品推荐

