Acumatica - 交叉引用

Acumatica - Cross Referencing

我的DAC和表格定义如下 数据结构

ParentTableDAC(窗体视图) ChildDac1 (TAb1/Grid) ChildDac2 (Tab2/Grid)

在 ChildDAc2 中,ChildDAc1ID 需要显示为 Selector,如何实现? 如果未为 Parent/ChildDAc1 保存数据,我们将面临问题,那么它对 ChildDAc2 Lookup

不可用

更新- 业务场景 - 一个工作项有多个任务和多个步骤来执行该工作项。 现在 WORKITEMDAC 是父项 TASKDAC 和 STEPDAC 是父 WORKITEMDAC 的子对象。 好的,直到一切都正常。 现在假设每个步骤都与父 WORKITEM 的任务相关联。 因此在 STEPS Grid 中需要一个选择器来 select 任务。 在这里我有适当的父子关系没有问题,我只有一个问题,我可以 select 只有已经用父 WORKITEM 保存的任务,未保存的任务不会显示在 select或者。 所以我的问题是,我们有没有办法在尚未保存的 PXSelector 查询中获取任务? 以下选择器用于 TaskID 列上的 STEPDAC - [PXSelector(typeof(Search>>), typeof(TASKDAC.taskCD), SubstituteKey = typeof(TASKDAC.taskCD))]

注意 - TASKDAC 中的 TaskID 列是标识列,此 DAC 将 WorkItemID 定义为 PArent。

更新

感谢您提供更详细的更新。为那些可能需要有关 parent/child.

的人保留下面的原始回复

我从未见过 select 或参考 Current<> 而没有 Current WHAT 的定义。老实说,我很惊讶它的编译。 “Where Field = Current View Field”指示 selector 将结果限制为仅与您指定的任何字段的当前值关联的值,并且它是从图表中的“ViewName.Current”记录中检索的.您的 where 子句没有告诉它匹配什么“当前”。由于您将 selector 指向搜索,我怀疑这会导致 selector 无法找到匹配的记录并且 short-circuiting 无法保存该字段的结果。

听起来 TASKDAC 是一种“主数据”类型的记录,定义了所有可能要执行的任务。因此,TaskID 不是 STEPDAC 中的关键字段,而是 TASKDAC 中的关键字段。如果你想 select “任何”任务,你根本不需要 where 子句。

[PXSelector(
    typeof(TASKDAC.TaskID),
    typeof(TASKDAC.taskCD),
    SubstituteKey = typeof(TASKDAC.taskCD)
)]

让我们暂时假设您指定一个 WORKITEMDAC.WorkOrderType 用于按同一字段过滤 acceptable 任务。 (只能将维修任务分配给维修 WorkOrderType,将装配分配给装配 WorkOrderType,等等)在这种情况下,您将使用您声明的语法,但您将指定 Where>。如果任务仅限于 STEPDAC 中的某些内容,只需在下面的示例中将 WORKITEMDAC 替换为 STEPDAC 字段即可。

[PXSelector(
    typeof(Search<TASKDAC.TaskID,
        Where<TASKDAC.WorkOrderType, Equal<Current<WORKITEMDAC.WorkOrderType>>>>),
    typeof(TASKDAC.taskCD),
    SubstituteKey = typeof(TASKDAC.taskCD)
)]

请更新您的 PXSelector 并告知是否可以解决问题或接下来会出现什么错误。

原始回复

你的问题太少了,你的问题的性质很不清楚。听起来您正在尝试做一些可能应该采取不同方法的事情。 selector 的定义不应影响字段的保存,但 parent child 关系的结构对于正确定义至关重要。因此,您拥有一个不同于 parent 的 Child ID 并且它会在 selector.

中使用,这似乎很奇怪

通常,child DAC 与 parent DAC 共享一个 ID。我们经常在child中定义一个LineNbr字段,由PXLineNbrAttribute赋值,Key字段为ID+LineNbr来标识特定的child记录。我们还在网格上的 ASPX 文档中设置 SyncPosition = true,以便用户界面与用户在网格中 selected 的任何记录保持完全同步。 Parent Child 关系可以菊花链式连接,例如 SOOrder -> SOLine -> SOLineSplit,但最终,child 的 ID 字段不是 selector。 .. parent 的 ID 是

将 selector 视为查找主数据的一种方式。主数据可能与其他数据相关,但在大多数情况下不会有 parent。有例外,但让我们保持简单。例如,采购订单不会有 parent,关键字段将是一个常见的 selector 字段。但是,由于 child 必须始终与其 parent 相关并且不能更改其 parent,因此 child 字段的 ID 不会是 selector。 Acumatica 中的其他 table 会引用某些字段或字段组合以与 child DAC 的数据相关。

为了说明这一点,我从 T210 培训指南中删除了很多内容。

RSSVRepairPrice - Parent

using System;
using PX.Data;

namespace PhoneRepairShop
{
    [PXCacheName("Repair Price")]
    public class RSSVRepairPrice : IBqlTable
    {
        #region PriceID
        [PXDBIdentity]
        public virtual int? PriceID { get; set; }
        public abstract class priceID : PX.Data.BQL.BqlInt.Field<priceID> { }
        #endregion

        #region ServiceID
        [PXDBInt(IsKey = true)]
        [PXDefault]
        [PXUIField(DisplayName = "Service", Required = true)]
        [PXSelector(
            typeof(Search<RSSVRepairService.serviceID>),
            typeof(RSSVRepairService.serviceCD),
            typeof(RSSVRepairService.description),
            DescriptionField = typeof(RSSVRepairService.description),
            SelectorMode = PXSelectorMode.DisplayModeText)]
        public virtual int? ServiceID { get; set; }
        public abstract class serviceID : PX.Data.BQL.BqlInt.Field<serviceID> { }
        #endregion

        #region RepairItemLineCntr
        [PXDBInt()]
        [PXDefault(0)]
        public virtual Int32? RepairItemLineCntr { get; set; }
        public abstract class repairItemLineCntr : PX.Data.BQL.BqlInt.Field<repairItemLineCntr> { }
        #endregion

    }
}

RSSVRepairItem - Child

using System;
using PX.Data;
using PX.Objects.IN;
using PX.Data.BQL.Fluent;

namespace PhoneRepairShop
{
    [PXCacheName("Repair Item")]
    public class RSSVRepairItem : IBqlTable
    {
        #region ServiceID
        [PXDBInt(IsKey = true)]
        [PXDBDefault(typeof(RSSVRepairPrice.serviceID))]
        [PXParent(
            typeof(SelectFrom<RSSVRepairPrice>.
            Where<RSSVRepairPrice.serviceID.IsEqual<
            RSSVRepairItem.serviceID.FromCurrent>>
            ))]
        public virtual int? ServiceID { get; set; }
        public abstract class serviceID : PX.Data.BQL.BqlInt.Field<serviceID> { }
        #endregion

        #region LineNbr
        [PXDBInt(IsKey = true)]
        [PXLineNbr(typeof(RSSVRepairPrice.repairItemLineCntr))]
        [PXUIField(DisplayName = "Line Nbr.", Visible = false)]
        public virtual int? LineNbr { get; set; }
        public abstract class lineNbr : PX.Data.BQL.BqlInt.Field<lineNbr> { }
        #endregion

    }
}

在parent中,注意PXDBIdentityAttribute 的使用,它指定记录标识由数据库在PriceID 中设置。 child 使用的“ID”字段取自定义为 select 或另一个主 table 的 ServiceID 字段。在 PXDBIntAttribute 上使用 IsKey = true 告诉 Acumatica 它可以通过标记为 IsKey = true 的所有字段的组合找到唯一记录。 (请注意,实际培训指南包括另一个字段作为键的一部分,但我在这里简化了示例。)还要注意使用默认值为 0 的 PDXBInt 字段用作行计数器。 (RepairItemLineCtr)

现在,在 child 中,请注意 parent 的关键字段在 DAC 中再次定义,但没有 selector。 PXParent 属性定义了与 parent DAC 的关系,字段值默认来自 parent。这就是导致值自动保存在记录中的原因。它还关联关系,以便删除 parent 也会删除 child。请注意使用 PXLineNbrAttribute 来自动递增 parent DAC 的字段并在 LineNbr 字段中设置值。正是这 2 个字段的组合将您指向确切的记录。

在某些情况下,Acumatica 使用 NoteID 字段(一个独特的 GUIvalue) 来识别 child DAC 的记录,但这有点复杂。您可以在 INItemPlan(需求)与采购订单的关系中看到它。

如果您在 Parent-Child (Master-Detail) 关系方面遇到问题,我强烈建议您查看 T210 training course

要引用未保存的数据,请在 PXSelector 上使用 ISDirty =true。 还要在引用位置保存未保存数据的标识键值,使用 [PXDBDefault()]