我有两个自定义表(标题/详细信息),它们有多个字段作为两者的键。我已经在Header的详细选择中创建了所有PXParent和PXDefault属性,就像在T200课程中所示。
问题在于,当我在标题部分有关键字段并尝试创建新记录时,表单不会清除我为这些关键字段选择的值。
我继续创建一个自动递增的int标识字段作为键,而其他以前的关键字段组装成一个唯一的索引。我在我的DAC中使用PXDBIdentity(IsKey = true)属性 - 除了一个问题之外它运行良好:当我创建一个新记录时,该字段显示-2147483647直到我保存,然后它显示新创建的标识值
所以我想我的问题是:
当该表的唯一标识由6个字段组成时,为自定义表创建关键字段的标准协议/最佳实践是什么?如果我正确地做了,如何消除-2147483647在ID字段中的显示?
答案 0 :(得分:0)
标识字段的问题在于数字是由数据库生成的,而不是由ORM生成的,ORM通常在记录持续存储之前保存缓存中的新插入行。我的建议是从UI中删除身份或找出不同的密钥。
答案 1 :(得分:0)
在定义DAC中的关键字段时,只有一条主要规则:
只有绑定到标识列的字段才能成为DAC中唯一的关键字段
只要没有定义的关键字段绑定到标识列,您就可以在DAC中定义几个关键字段
框架提供的标准 PXInsert 操作会保留除最后一个之外的所有关键字段的值。如果希望“插入”按钮清除所有键字段的值,则可以从PXInsert<TNode>
类继承并在执行基本逻辑之前清除搜索数组:
public class MyGraph : PXGraph<MyGraph>
{
public class PXInsertCst<TNode> : PXInsert<TNode>
where TNode : class, IBqlTable, new()
{
public PXInsertCst(PXGraph graph, string name)
: base(graph, name)
{
}
public PXInsertCst(PXGraph graph, Delegate handler)
: base(graph, handler)
{
}
[PXUIField(DisplayName = ActionsMessages.Insert,
MapEnableRights = PXCacheRights.Insert,
MapViewRights = PXCacheRights.Insert)]
[PXInsertButton]
protected override IEnumerable Handler(PXAdapter adapter)
{
adapter.Searches = null;
return base.Handler(adapter);
}
}
public PXSave<MyPrimaryDAC> Save;
public PXCancel<MyPrimaryDAC> Cancel;
// The standard PXInsert type was replaced with the custom PXInsertCst type
public PXInsertCst<MyPrimaryDAC> Insert;
public PXDelete<MyPrimaryDAC> Delete;
public PXCopyPasteAction<MyPrimaryDAC> CopyPaste;
public PXFirst<MyPrimaryDAC> First;
public PXPrevious<MyPrimaryDAC> Previous;
public PXNext<MyPrimaryDAC> Next;
public PXLast<MyPrimaryDAC> Last;
}
如果要求显示唯一的DAC键字段绑定UI中的标识列,但用户不希望看到为新记录生成的临时负值,则应实现<以下代码示例后面的DAC的标识列映射字段的strong> FieldSelecting 和 FieldUpdating 事件处理程序:
public class MyGraph : PXGraph<MyGraph>
{
protected void MyDAC_IdentityField_FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
{
if (e.Row != null && e.ReturnValue is int?)
{
if ((e.ReturnValue as int?).GetValueOrDefault() < 0)
{
e.ReturnValue = null;
}
}
}
protected void MyDAC_IdentityField_FieldUpdating(PXCache sender, PXFieldUpdatingEventArgs e)
{
if (e.Row != null && e.NewValue == null && sender.Inserted.Count() == 1)
{
var defaultValue = sender.GetValue<MyDAC.identityField>(sender.Inserted.FirstOrDefault_());
if (defaultValue != null)
{
e.NewValue = defaultValue;
}
}
}
}
对于DAC级别的更通用方法,您可以实现从PXDBIdentityAttribute
继承的自定义属性,并在代码后面覆盖 FieldSelecting 和 FieldUpdating 事件处理程序示例如下:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter |
AttributeTargets.Class | AttributeTargets.Method)]
public class PXDBNewIdentityAttribute : PXDBIdentityAttribute
{
public override void FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
{
base.FieldSelecting(sender, e);
if (e.Row != null && e.ReturnValue is int?)
{
if ((e.ReturnValue as int?).GetValueOrDefault() < 0)
{
e.ReturnValue = null;
}
}
}
public override void FieldUpdating(PXCache sender, PXFieldUpdatingEventArgs e)
{
if (e.Row != null && e.NewValue == null && sender.Inserted.Count() == 1)
{
var defaultValue = sender.GetValue(sender.Inserted.FirstOrDefault_(), FieldOrdinal);
if (defaultValue != null)
{
e.NewValue = defaultValue;
}
}
base.FieldUpdating(sender, e);
}
}