保存亲子

时间:2017-07-03 07:51:14

标签: acumatica

我正在使用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的用途吗?

2 个答案:

答案 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之后)