如何向DataMember为未绑定DAC的Acumatica网格插入多行数据
问题根因
只能插入首行是两个代码错误共同导致的:
- 未绑定DAC定义不符合框架要求:Acumatica的PXCache必须通过键字段唯一区分不同记录,当前UnboundDAC没有标记任何键字段,框架会默认把所有字段作为联合键做去重判断;同时字段上使用了面向数据库持久化的
[PXDBInt]特性,未绑定场景下会触发异常的存在性校验,第二次插入时框架判定缓存中已存在同键记录,直接返回首行对象,不会生成新行。 - 视图类型选型错误:
PXFilter<T>是专门为单条筛选条件设计的视图类型,本身仅维护单条当前记录,天生不支持存储多行数据列表,不能作为多行网格的数据源。
修复方案
1. 修正UnboundDAC定义
给DAC新增唯一行号字段作为主键,同时将所有数据库绑定特性替换为未绑定字段专用特性:
using System; using PX.Data; namespace NS { [Serializable] [PXCacheName("UnboundDAC")] public class UnboundDAC : IBqlTable { #region LineNbr // 新增行号字段作为唯一主键 [PXInt(IsKey = true)] // 若主DAC MainDAC上定义了lineCntr行计数字段,可直接用PXLineNbr特性自动维护行号 [PXLineNbr(typeof(MainDAC.lineCntr))] [PXUIField(DisplayName = "Line Nbr.", Visible = false)] public virtual int? LineNbr {get; set; } public abstract class lineNbr : PX.Data.BQL.BqlInt.Field<lineNbr> { } #endregion #region IntField // 替换数据库绑定特性PXDBInt为未绑定字段用的PXInt [PXInt] [PXUIField(DisplayName = "Int Field")] public virtual int? IntField {get; set; } public abstract class intField : PX.Data.BQL.BqlInt.Field<intField> { } #endregion } }
如果主DAC没有定义行计数器,去掉[PXLineNbr]特性,在插入逻辑中手动维护行号即可。
2. 修正视图定义与插入逻辑
将PXFilter替换为支持多行存储的PXSelect视图,调整插入逻辑确保新行能被网格识别:
// 替换PXFilter为PXSelect作为网格数据源 public PXSelect<UnboundDAC> GridView; // 未绑定场景下建议添加视图委托,直接返回缓存中的记录,避免框架尝试查询不存在的数据库表 protected virtual IEnumerable gridView() { return GridView.Cache.Cached; } public PXAction<MainDAC> InsertRow; [PXButton(CommitChanges = true)] [PXUIField(DisplayName = "Insert Row")] protected void insertRow() { UnboundDAC newline = new UnboundDAC(); newline.IntField = Document.Current.FormIntField; // 如果没有用PXLineNbr特性自动维护行号,打开下方注释手动赋值唯一行号 // int maxLine = 0; // foreach (UnboundDAC exist in GridView.Cache.Cached) // { // if ((exist.LineNbr ?? 0) > maxLine) maxLine = exist.LineNbr.Value; // } // newline.LineNbr = maxLine + 1; GridView.Insert(newline); // 插入后触发视图刷新,确保网格立刻展示新行 GridView.View.RequestRefresh(); }
注意事项
- 未绑定DAC的所有字段禁止使用带
DB前缀的特性(如PXDBString、PXDBInt、PXDBBool等),这类特性会让框架尝试做数据库表映射校验,未绑定场景下会触发各类不可预期的错误。 - 检查前端网格控件配置,确保
AllowInsert、AllowUpdate属性已开启,不要设置过滤条件拦截新增行的展示。 - 如果需要在回发后保留未绑定行的数据,需要在视图层面重写持久化逻辑,手动将缓存中的未绑定数据存到会话或视图状态中。
内容的提问来源于stack exchange,提问作者Jeremy Valdez
相关产品推荐
相关产品推荐

