首页 > 解决方案 > 如何在不使用 fieldname.Length 的情况下获得 DAC 字段的最大长度?

问题描述

当为 SO 记录选择 SOOrder.ShipVia 时,我有一个客户端请求将 SOOrder.ShipTermsID 值与“匹配”SOOrder.ShipVia 值匹配(此处的“匹配”意味着 ID 尽可能相同)。他们希望这些字段始终对应。因此,我从 SOOrderEntry 扩展中的以下内容开始:

\\other using statements
using PX.Objects.CS;

namespace PX.Objects.SO
{
    public class SOOrderEntry_Extension : PXGraphExtension<SOOrderEntry>
    {
        protected virtual void _(Events.FieldUpdated<SOOrder, SOOrder.shipVia> e)
        {
            if (e.Row == null || e.Row.ShipVia == null) return;
            ShipTerms term = PXSelectReadonly<ShipTerms,
                Where<ShipTerms.shipTermsID, Equal<Required<ShipTerms.shipTermsID>>>>
                .Select(Base, e.Row.ShipVia);
            e.Row.ShipTermsID = term?.ShipTermsID;
        }
    }
}

但是,SOOrder.ShipVia 和 SOOrder.ShipTermsID 字段的长度不同。在 DB 和 DAC 声明中,它们分别是 nvarchar(15) 和 nvarchar(10)。

好的,所以我需要将 ShipVia 中的值截断为与 ShipTermsID 相同的长度。但是,如果这个值在 Acumatica 中发生变化,我想编写我的代码,这样它就不会依赖硬编码的值。因此,我的下一个想法是执行以下操作:

    protected virtual void _(Events.FieldUpdated<SOOrder, SOOrder.shipVia> e)
    {
        if (e.Row == null || e.Row.ShipVia == null) return;
        ShipTerms term = PXSelectReadonly<ShipTerms,
            Where<ShipTerms.shipTermsID, Equal<Required<ShipTerms.shipTermsID>>>>
            .Select(Base, e.Row.ShipVia.Substring(0, e.Row.ShipTermsID.Length));
        e.Row.ShipTermsID = term?.ShipTermsID;
    }

但这失败了,因为此时 e.Row.ShipTermsID 值为 NULL,因此 Length 返回 NULL 并且屏幕抛出异常。

我在网上找到了大量关于如何获取 DB Schema 信息的信息,但我发现的一切似乎都希望我打开一个新的 DB 连接字符串。我不确定这是最好的方法,我担心潜在的性能问题。此外,如果 DAC 字段比 DB 字段短,那么 Schema 信息无论如何也无济于事,所以我需要 DAC 字段长度。

如果我最终只需要为此使用一个常量,我可以,但我想避免这种情况,以免将来遇到麻烦,如果不是针对这个特定领域,那么至少我下次会知道。

如何在不使用 fieldname.Length 的情况下从 a 中检索 DAC 字段的最大长度?

标签: acumatica

解决方案


从 Acumatica 2018R2 版本开始,还有另一种方法可以做同样的事情,甚至可以使用方法调整任何属性属性。PXCache.Adjust这种方式得到了 Acumatica 平台团队的认可,并且比PXCache.GetAttributesReadOnly由于更高的代码级别更好。

protected virtual void _(Events.FieldUpdated<SOOrder, SOOrder.shipVia> e)
{
    if (e.Row == null || e.Row.ShipVia == null) return;

    int length = 0;
    e.Cache.Graph.Caches[typeof(ShipTerms)]
        .Adjust<PXDBStringAttribute>()
        .For<ShipTerms.shipTermsID>(attr => length = attr?.Length ?? 0);

    ShipTerms term = PXSelectReadonly<ShipTerms,
        Where<ShipTerms.shipTermsID, Equal<Required<ShipTerms.shipTermsID>>>>
        .Select(Base, e.Row.ShipVia.Substring(0, Math.Min(e.Row.ShipVia.Length, length)));
    e.Row.ShipTermsID = term?.ShipTermsID;
}

推荐阅读