You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何传递DAC字段参数重构Acumatica的DisplayName获取代码?

问题

我有一段重复执行的代码,用于从指定DAC的各字段中获取DAC字段的DisplayName属性,希望将该代码重构为函数并仅传递必要参数,但无法找到优雅的方式处理DAC字段参数。

重复使用的代码示例:

string displayName = string.Empty;

foreach (PXEventSubscriberAttribute attribute in ext.DefAddress.Cache.GetAttributes<Address.countryID>(newaddr))
{
    if (attribute is PXUIFieldAttribute)
    {
        PXUIFieldAttribute attrib = attribute as PXUIFieldAttribute;
        displayName = attrib.DisplayName;
    }
}

期望的函数调用形式:

string displayName = GetDisplayName(Address.addressLine1, ext.DefAddress.Cache, newaddr);

其中Address.addressLine1为DAC字段,ext.DefAddress.Cache为PXCache实例,newaddr为Address DAC对象。

我尝试的函数无法运行:

protected string GetDisplayName(Type field, PXCache cache, Address DAC)
{
    foreach (PXEventSubscriberAttribute attribute in cache.GetAttributes<field>(DAC))
    {
        if (attribute is PXUIFieldAttribute)
        {
            PXUIFieldAttribute attrib = attribute as PXUIFieldAttribute;
            displayName = attrib.DisplayName;
        }
    }
}

无论尝试多少次,都无法解决如何将DAC字段作为参数传入函数的问题,希望得到帮助!

解决方案

在Acumatica中,PXCache.GetAttributes<TField>是泛型方法,无法直接通过Type参数动态指定泛型类型。以下是两种可行的优雅实现方式:

方法1:基于字段名的类型安全调用

利用nameof关键字避免硬编码字段名,结合PXCache.GetAttributes的非泛型重载:

protected string GetDisplayName(PXCache cache, object dac, string fieldName)
{
    foreach (PXEventSubscriberAttribute attribute in cache.GetAttributes(dac, fieldName))
    {
        if (attribute is PXUIFieldAttribute uiField)
        {
            return uiField.DisplayName;
        }
    }
    return string.Empty;
}

调用示例:

string displayName = GetDisplayName(ext.DefAddress.Cache, newaddr, nameof(Address.addressLine1));

方法2:Lambda表达式实现完全类型安全

通过Lambda表达式传递字段,编译时即可校验字段合法性,完全符合你期望的调用形式:

using System.Linq.Expressions;

protected string GetDisplayName<TEntity, TField>(PXCache cache, TEntity dac, Expression<Func<TEntity, TField>> fieldExpression)
{
    var memberExpression = fieldExpression.Body as MemberExpression;
    if (memberExpression == null) return string.Empty;

    string fieldName = memberExpression.Member.Name;
    foreach (PXEventSubscriberAttribute attribute in cache.GetAttributes(dac, fieldName))
    {
        if (attribute is PXUIFieldAttribute uiField)
        {
            return uiField.DisplayName;
        }
    }
    return string.Empty;
}

调用示例:

string displayName = GetDisplayName(ext.DefAddress.Cache, newaddr, x => x.addressLine1);

关键优化点

  • 修正原代码中string.Empty()的错误写法,应为string.Empty
  • 找到PXUIFieldAttribute后立即返回,无需遍历全部属性,提升执行效率
  • 两种方法均兼容Acumatica的DAC属性获取逻辑,适配不同场景需求

内容的提问来源于stack exchange,提问作者KDub97

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 04:30:26