我有一个带有自定义父级DAC记录的方案,其中我需要为每个父级扩展基本DAC,并添加特定于该父级的其他数据。
例如,我需要为每个Warehouse(INSite)记录存储其他数据,但是对于每个自定义父记录,其他数据将有所不同。因此,我的子级DAC将需要对ParentDAC的密钥,INSite的密钥以及该特定Parent + INSite的其他自定义数据字段的密钥引用。
在“表单/标签维护”屏幕中,用户将选择自定义的父记录,然后明细网格应显示所有现有的仓库(INSite)记录以及参考字段(SiteCD,描述)和自定义字段,以便用户可以提供该父+ INSite的其他数据。 子记录最初可能不存在(在初始配置时,或者如果创建了新的INSite记录),并且在最初创建时,当然需要使用加入的INSite中的SiteID和当前的父ID来默认它们。
我尝试使用“左外部连接”扩展表来实现此目的,由于需要附加的父记录键字段,该表似乎不起作用。
我还尝试过使用PXProjection,由于似乎无法将子记录的关键字段初始化为Joined INSite记录的值,因此它似乎也不起作用。
在维护屏幕中,通过以下操作,我能够通过自定义View委托接近所需的功能。
namespace DevTest {
[Serializable]
public class ParentDAC : IBqlTable
{
[PXDBString(10, IsKey = true)]
[PXUIField(DisplayName = "Parent ID")]
[PXSelector(typeof(ParentDAC.parentID), ValidateValue = false)]
public string ParentID { get; set; }
public abstract class parentID : IBqlField { }
}
[Serializable]
public class INSiteCompanion : IBqlTable
{
[PXDBString(10, IsKey = true)]
[PXDBDefault(typeof(ParentDAC.parentID))]
[PXParent(typeof(Select<ParentDAC, Where<ParentDAC.parentID, Equal<Current<INSiteCompanion.parentID>>>>))]
public virtual string ParentID { get; set; }
public abstract class parentID : IBqlField { }
[PXDBInt(IsKey = true)]
public virtual int? SiteID { get; set; }
public abstract class siteID : IBqlField { }
[PXDBBool]
[PXUIField(DisplayName = "Included")]
public virtual bool? Included { get; set; }
public abstract class included : IBqlField { }
[PXString(30)]
[PXUIField(DisplayName = "Warehoue ID", Enabled = false)]
public virtual string SiteCD { get; set; }
public abstract class siteCD : IBqlField { }
[PXString(60)]
[PXUIField(DisplayName = "Description", Enabled = false)]
public virtual string Descr { get; set; }
public abstract class descr : IBqlField { }
}
public class ParentDACMaint : PXGraph<ParentDACMaint, ParentDAC>
{
public PXSelect<ParentDAC> Parents;
public PXSelect<INSiteCompanion> Sites;
public virtual IEnumerable sites()
{
ParentDAC parent = Parents.Current;
PXCache cache = Sites.Cache;
bool wasDirty = cache.IsDirty;
foreach (PXResult<ParentDAC, INSite, INSetup, INSiteCompanion> row in PXSelectReadonly2<ParentDAC,
CrossJoin<INSite,
CrossJoin<INSetup,
LeftJoin<INSiteCompanion, On<INSiteCompanion.parentID, Equal<ParentDAC.parentID>,
And<INSiteCompanion.siteID, Equal<INSite.siteID>>>>>>,
Where<Current<ParentDAC.parentID>, IsNotNull,
And<INSite.active, Equal<True>,
And<INSite.siteID, NotEqual<INSetup.transitSiteID>,
And<Where<ParentDAC.parentID, Equal<Current<ParentDAC.parentID>>, Or<ParentDAC.parentID, IsNull>>>>>>,
OrderBy<Asc<INSite.siteCD>>>.Select(this))
{
var record = (INSiteCompanion)row;
var site = (INSite)row;
// Initialize Key fields
record.ParentID = parent.ParentID;
record.SiteID = site.SiteID;
// Initialize reference fields
record.SiteCD = site.SiteCD;
record.Descr = site.Descr;
yield return record;
}
cache.IsDirty = wasDirty;
}
}
}
<%@ Page Language="C#" MasterPageFile="~/MasterPages/FormTab.master" AutoEventWireup="true"
ValidateRequest="false" CodeFile="AA103000.aspx.cs" Inherits="Page_AA103000" Title="Untitled Page" %>
<%@ MasterType VirtualPath="~/MasterPages/FormTab.master" %>
<asp:Content ID="cont1" ContentPlaceHolderID="phDS" runat="Server">
<px:PXDataSource ID="ds" runat="server" Visible="True" Width="100%" PrimaryView="Parents" TypeName="DevTest.ParentDACMaint">
</px:PXDataSource>
</asp:Content>
<asp:Content ID="cont2" ContentPlaceHolderID="phF" runat="Server">
<px:PXFormView ID="form" runat="server" DataSourceID="ds" Style="z-index: 100" Width="100%" DataMember="Parents" TabIndex="100">
<Template>
<px:PXLayoutRule runat="server" StartRow="True"/>
<px:PXSelector ID="edParentID" runat="server" DataField="ParentID" />
</Template>
</px:PXFormView>
</asp:Content>
<asp:Content ID="cont3" ContentPlaceHolderID="phG" runat="Server">
<px:PXTab ID="tab" runat="server" Width="100%" Height="150px" DataSourceID="ds">
<Items>
<px:PXTabItem Text="Place Holder">
<Template>
<px:PXLabel ID="PXLabel1" runat="server" AlreadyLocalized="False">Place Holder</px:PXLabel>
</Template>
</px:PXTabItem>
<px:PXTabItem Text="Warehouses">
<Template>
<px:PXGrid ID="PXGrid3" runat="server">
<Levels>
<px:PXGridLevel DataMember="Sites">
<RowTemplate>
<px:PXTextEdit ID="edSiteCD" runat="server" AlreadyLocalized="False" DataField="SiteCD" DefaultLocale="" />
<px:PXTextEdit ID="edDescr" runat="server" AlreadyLocalized="False" DataField="Descr" DefaultLocale="" />
<px:PXCheckBox ID="edIncluded" runat="server" AlreadyLocalized="False" DataField="Included" Text="Included" />
</RowTemplate>
<Columns>
<px:PXGridColumn DataField="SiteCD" Width="140px" />
<px:PXGridColumn DataField="Descr" Width="220px" />
<px:PXGridColumn DataField="Included" TextAlign="Center" Type="CheckBox" Width="60px" />
</Columns>
</px:PXGridLevel>
</Levels>
</px:PXGrid>
</Template>
</px:PXTabItem>
</Items>
<AutoSize Container="Window" Enabled="True" MinHeight="150" />
</px:PXTab>
</asp:Content>
但这也有一些小问题,其中在更新自定义数据并导航到其他记录时,参考字段(SiteCD,说明)为空白(尽管这似乎仅在Tab容器中发生-简单的Form / Detail)似乎没有这个问题)。保存并且网格刷新时,参考字段会刷新,并且数据确实会保留正确的键值。
是否存在实现此类功能的适当方法,或者这是最佳方法?关于在更新网格中的字段时更改参考字段的任何解释?
答案 0 :(得分:0)
PXParent仅设计用于静态主键和外键。
它与从SQL数据库提供程序继承的约束紧密匹配。
documentation中有关使用父级关系的相关代码示例:
public partial class SOLine : PX.Data.IBqlTable
{
public class SOOrderFK : SOOrder.PK.ForeignKeyOf<SOLine>
.By<orderType, orderNbr> { }
public class InventoryFK : InventoryItem.PK.ForeignKeyOf<SOLine>
.By<inventoryID> { }
public abstract class orderType : PX.Data.IBqlField { }
[...]
[PXParent(typeof(SOOrderFK))]
public virtual String OrderNbr { get; set; }
public abstract class orderNbr : PX.Data.IBqlField { }
[...]
[PXForeignReference(typeof(InventoryFK))]
public virtual Int32? InventoryID { get; set; }
public abstract class inventoryID : PX.Data.IBqlField { }
}