既然您要求“更好的整体方法”,那么我将分享我的首选处理方式。并不是说它“更好”,但也许只是“不同”。
我尝试将我的数据与直接相关的对象绑定。对于 InventoryItem 的属性,我会将该属性值提升为 DAC 扩展中的 InventoryItem,以便在使用 InventoryItem 的任何地方都可以利用它。您似乎想将它与 SOLine 记录结合使用,但由于该属性未绑定到 SOLine,因此我不会扩展 SOLine 来添加它。如果您的业务需求要求,将其添加到那里并没有错,但是知道 InventoryItem 的相关数据来自 InventoryItem 让我更加清醒,而不是试图记住我把它放在哪里并可能在其他地方重复工作(比如在POLine) 稍后。
这是我如何完成它的示例,直接从我的项目中提取,但将属性引用更改为更通用。
public sealed class InventoryItemExt : PXCacheExtension<PX.Objects.IN.InventoryItem>
{
#region MyAttribute
[PXString]
[PXUIField(DisplayName = Messages.MyAttribDisplayName)]
[PXDBScalar(typeof(Search<CSAnswers.value,
Where<CSAnswers.refNoteID, Equal<InventoryItem.noteID>,
And<CSAnswers.attributeID, Equal<MyAttribute>>>>))]
public string MyAttribute { get; set; }
public abstract class myAttribute : PX.Data.BQL.BqlString.Field<myAttribute> { }
#endregion
public class MyAttribute : PX.Data.BQL.BqlString.Constant<MyAttribute>
{
public MyAttribute() : base("MYATTRIB") { }
}
}
注意为访问附加到 InventoryItem 记录的项目类的 AttributeID“MYATTRIB”而定义的常量。
现在该属性已被拉入 InventoryItem 的 DAC 扩展中,只要 InventoryItem(和相关的 DAC 扩展)可用于该屏幕,我就可以轻松地在与 InventoryItem 相关的任何屏幕上使用它。
如果没有测试,我可能会反对,但关于您尝试在 PXDBScalar 中加入 2 个表...
当您说 Search2 时,表示您要搜索 CSAnswers DAC 并检索 value 字段。通过随后尝试 InnerJoin 回到 CSAnswers,我相信您实际上已经说过:
Select CSAnswers.Value From CSAnswers
Inner Join InventoryItem On SOLine.InventoryID = InventoryItem.InventoryID
Inner Join CSAnswers...
我不确定 SOLine 参考在此处是否有效,但如果您直接在 SOLine DAC 扩展中定义它可能是有效的。但是,您尝试查询 CSAnswers Inner Join CSAnswers。不确定这是否会修复您的 PXDBScalar,但如果您真的想使用您的方法将其附加到 SOLine,请尝试:
Search2<CSAnswers.value,
InnerJoin<InventoryItem,
On<InventoryItem.inventoryID, Equal<SOLine.inventoryID>>>,
Where<InventoryItem.noteID, Equal<CSAnswers.refNoteID>,
And<CSAnswers.attributeID, Equal<QHOLDAttr>>>
>))]
(请注意,我在 On 子句中交换了关系的顺序。)