我正在使用Acumatica Framework创建一个图表,我正在尝试保存对数据库的更改,但我收到了保存错误。
我有一个典型的父/子(即主/细节)关系,一切都应该正确设置。
我的孩子DAC有PXDBDefault和PXParent条目:
[PXDBInt()]
[PXDBDefault(typeof(DCRuleHeader.ruleHeaderID))]
[PXParent(typeof(Select<DCRuleHeader, Where<DCRuleHeader.ruleHeaderID, Equal<Current<DCRule.ruleHeaderID>>>>))]
public virtual int? RuleHeaderID
{
get
{
return this._RuleHeaderID;
}
set
{
this._RuleHeaderID = value;
}
}
在标题中,ID是数据库中的标识,并在DAC中定义为密钥,如下所示:
[PXDBIdentity(IsKey = true)]
[PXUIField(Enabled = false)]
public virtual int? RuleHeaderID
{
get
{
return this._RuleHeaderID;
}
set
{
this._RuleHeaderID = value;
}
}
视图也相应配置:
public class RulesMaint : PXGraph<RulesMaint, DCRuleHeader>
{
public PXSelect<DCRuleHeader> RuleHeader;
public PXSelect<DCRule, Where<DCRule.ruleHeaderID, Equal<Current<DCRuleHeader.ruleHeaderID>>>> Rules;
public PXAction<DCRuleHeader> ViewRule;
但是,以下代码无效
RulesMaint rulesGraph = PXGraph.CreateInstance<RulesMaint>();
DCRuleHeader newHeader = rulesGraph.RuleHeader.Insert();
...
DCRule rule = rulesGraph.Rules.Insert();
...
rulesGraph.Actions.PressSave();
当我尝试上述操作时,我收到错误&#39;错误&#34; RuleHeaderID&#34;不能为空&#39;
框架是否应该自己处理所有内容并自动设置子对象的父ID?不是PXDBDefault的用途吗?
答案 0 :(得分:2)
以下示例说明如何使用Acumatica ERP中的“表单详细信息”视图获取父/子DAC。 对于乞讨,让我们以下列方式为父和子创建SQL表: 家长:
/****** Object: Table [dbo].[SOCustomParentTable] Script Date: 07/03/2017 12:55:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[SOCustomParentTable](
[CompanyID] [int] NOT NULL,
[ParentID] [int] IDENTITY(1,1) NOT NULL,
[Description] [nvarchar](255) NULL,
[SomeOtherField] [nvarchar](50) NULL,
[ParentCD] [nvarchar](15) NOT NULL
) ON [PRIMARY]
GO
和孩子一起
/****** Object: Table [dbo].[SOCustomChildTable] Script Date: 07/03/2017 12:54:39 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[SOCustomChildTable](
[CompanyID] [int] NOT NULL,
[ChildID] [int] IDENTITY(1,1) NOT NULL,
[ParentID] [int] NOT NULL,
[Description] [nvarchar](255) NULL,
[SomeOtherField] [nvarchar](50) NULL
) ON [PRIMARY]
GO
现在我们准备好SQL Tables,让我们创建DAC作为以下类:
家长:
using System;
using PX.Data;
namespace DemoParentChild
{
[Serializable]
public class SOCustomParentTable: IBqlTable
{
#region ParentID
[PXDBIdentity()]
public int? ParentID { get; set; }
public class parentID : IBqlField{}
#endregion
#region Description
[PXDBString(255, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Description")]
public string Description { get; set; }
public class description : IBqlField{}
#endregion
#region SomeOtherField
[PXDBString(50, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Some Other Field")]
public string SomeOtherField { get; set; }
public class someOtherField : IBqlField{}
#endregion
#region ParentCD
[PXDBString(15,IsKey = true, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Parent ID")]
public string ParentCD { get; set; }
public class parentCD : IBqlField{}
#endregion
}
}
孩子:
using System;
using PX.Data;
namespace DemoParentChild
{
[Serializable]
public class SOCustomChildTable: IBqlTable
{
#region ChildID
[PXDBIdentity(IsKey=true)]
public int? ChildID { get; set; }
public class childID : IBqlField{}
#endregion
#region ParentID
[PXDBInt()]
[PXDBDefault(typeof(SOCustomParentTable.parentID))]
[PXParent(typeof(Select<SOCustomParentTable, Where<SOCustomParentTable.parentID, Equal<Current<SOCustomChildTable.parentID>>>>))]
public int? ParentID { get; set; }
public class parentID : IBqlField{}
#endregion
#region Description
[PXDBString(255, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Description")]
public string Description { get; set; }
public class description : IBqlField{}
#endregion
#region SomeOtherField
[PXDBString(50, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Some Other Field")]
public string SomeOtherField { get; set; }
public class someOtherField : IBqlField{}
#endregion
}
}
为了完成我们的工作,让我们使用以下图表创建一个FormDetail类型的页面:
using System;
using PX.Data;
namespace DemoParentChild
{
public class tmp : PXGraph<tmp>
{
public PXSave<SOCustomParentTable> Save;
public PXCancel<SOCustomParentTable> Cancel;
public PXPrevious<SOCustomParentTable> Prev;
public PXNext<SOCustomParentTable> Next;
public PXSelect<SOCustomParentTable> MasterView;
public PXSelect<SOCustomChildTable,Where<SOCustomChildTable.parentID,Equal<Current<SOCustomParentTable.parentID>>>> DetailsView;
}
}
现在让我们了解这一切是如何运作的。 正如您所看到的,ParentID是SQL中的Identity,并且在DAC中设置为PXDBIdentity,但它没有设置为我们DAC的Key,因为我们将使用ParentCD作为可见Key。 同样在Child类中,ChildID设置为PXDBIdentity,但它也设置为Key,因为我们不需要该行具有用户的可见键。 同样在Child类中,我们有以下内容用于创建父/子关系:
[PXDBInt()]
[PXDBDefault(typeof(SOCustomParentTable.parentID))]
[PXParent(typeof(Select<SOCustomParentTable, Where<SOCustomParentTable.parentID, Equal<Current<SOCustomChildTable.parentID>>>>))]
public int? ParentID { get; set; }
PXDefault将Child的ParendID设置为当前Parent ID,PXParent正在创建当前Child与Parent之间的关系。
通常会在Parent上为子项和行计数器创建行号以了解Childs的计数。
您可以下载完整的自定义here
答案 1 :(得分:0)
我以前遇到过麻烦,因为我习惯于将新代码放在编辑器的顶部,结果表明数据视图选择(子级)应始终位于底部(在pxselect之后)