NetSuite自定义记录搜索:将结果转换为.NET对象列表

4
我唯一能够做到的方法是通过下面基于反射的代码。但是我不敢相信没有更简单的NetSuite方式来完成这个操作,难道我忽略了一些基础知识吗?
在对自定义对象执行搜索后,我会得到一个Record[]数组,然后可以循环遍历每个项目并将其转换为CustomObject
自定义对象的属性存储在CustomRecordcustomFieldList中,但是值不能立即访问,您需要将它们强制转换为其真实的NetSuite类型(如LongCustomFieldRefDoubleCustomFieldRefBooleanCustomFieldRefStringCustomFieldRef等)。
为了避免麻烦地获取干净的对象,我决定采用以下方法: 创建具有与NetSuite名称匹配(包括大小写)的属性名称的类,并从下面定义的NetSuiteBase继承。
public class MyNetSuiteObject : NetSuiteBase //<-- Note base class
{
    public string myProperty1 { get; set; }
    public bool myProperty2 { get; set; }
    public int myProperty3 { get; set; }

    public static MyNetSuiteObject FromCustomSearchRecord(CustomRecord customRecord)
    {
        var ret = new MyNetSuiteObject();
        ret.AssignProperties(customRecord);
        return ret;
    }
}

创建一个基类,该基类将检查CustomRecords并将属性值应用于.NET类。
public class NetSuiteBase
{

    public void AssignProperties(CustomRecord customRecord)
    {
        var classProps = this.GetType().GetProperties();
        foreach (var prop in classProps)
        {
            var propName = prop.Name;
            var propValue = prop.GetValue(this, null);

            //get the matching CustomFieldRef out of the customFieldList for the CustomRecord which matches our current property name
            var myCustomFieldRef = customRecord.customFieldList.Where(c => c.scriptId == propName).FirstOrDefault();

            if (myCustomFieldRef == null) continue;

            //we can't get the value out until we cast the CustomFieldRef to its "actual" type.
            var custType = myCustomFieldRef.GetType().Name;
            switch (custType)
            {
                case "LongCustomFieldRef":
                    TrySetProperty(prop, ((LongCustomFieldRef)myCustomFieldRef).value.ToString());
                    break;

                case "DoubleCustomFieldRef":
                    TrySetProperty(prop, ((DoubleCustomFieldRef)myCustomFieldRef).value.ToString());
                    break;

                case "BooleanCustomFieldRef":
                    TrySetProperty(prop, ((BooleanCustomFieldRef)myCustomFieldRef).value.ToString());
                    break;

                case "StringCustomFieldRef":
                    TrySetProperty(prop, ((StringCustomFieldRef)myCustomFieldRef).value.ToString());
                    break;

                case "DateCustomFieldRef":
                    TrySetProperty(prop, ((DateCustomFieldRef)myCustomFieldRef).value.ToString());
                    break;

                case "SelectCustomFieldRef":
                    TrySetProperty(prop, ((SelectCustomFieldRef)myCustomFieldRef).value.name.ToString());
                    break;

                case "MultiSelectCustomFieldRef":
                    TrySetProperty(prop, ((MultiSelectCustomFieldRef)myCustomFieldRef).value.ToString());
                    break;
                default:
                    Console.WriteLine("Unknown type: " + myCustomFieldRef.internalId);
                    break;
            }
        }
    }


    //Some of the NetSuite properties are represented as strings (I'm looking at you BOOLs), so we pass all the values from above
    //as strings and them process/attempt casts
    private void TrySetProperty(PropertyInfo prop, string value)
    {
        value = value.ToLower().Trim();

        if (prop.PropertyType == typeof(string))
        {
            prop.SetValue(this, value);
            return;
        }


        if (prop.PropertyType == typeof(bool))
        {
            if (value == "yes") value = "true";
            if (value == "no") value = "false";
            if (value == "1") value = "true";
            if (value == "0") value = "false";

            bool test;
            if (bool.TryParse(value, out test))
            {
                prop.SetValue(this, test);
                return;
            }
        }

        if (prop.PropertyType == typeof(int))
        {
            int test;
            if (int.TryParse(value, out test))
            {
                prop.SetValue(this, test);
                return;
            }
        }

        if (prop.PropertyType == typeof(double))
        {
            double test;
            if (double.TryParse(value, out test))
            {
                prop.SetValue(this, test);
                return;
            }
        }

        if (prop.PropertyType == typeof(decimal))
        {
            decimal test;
            if (decimal.TryParse(value, out test))
            {
                prop.SetValue(this, test);
                return;
            }
        }

    }
}

在对自定义对象进行NetSuite搜索后,循环遍历结果并使用上述类将NetSuite结果转换为.NET类

for (int i = 0, j = 0; i < records.Length; i++, j++)
{
    customRecord = (CustomRecord)records[i];

    var myNetSuiteObject = MyNetSuiteObject.FromCustomSearchRecord(customRecord);
}

有没有其他“NetSuite方式”来完成我上面所述的内容?
1个回答

0
不,没有“NetSuite”的方式。如果你问我,你所做的远远超出了职责范围,这太棒了。NetSuite/SuiteTalk WSDL 简直是可怕的,设计过程中做出了很多糟糕的选择,我很惊讶它被发布给开发人员时没有引起任何质疑。以下是另一个例子。

Bad API construction

这是他们的SuiteTalk课程文档,其中透露了当解析高级搜索结果时,它们包含SearchRowBasic对象。在每个SearchRowBasic对象中都有多个字段。要访问这些字段的值,您必须获取SearchColumnField数组的第一个元素。为什么要这样做?如果只会有一个值(并且他们在文档中确实声明只会有一个值),为什么要将返回对象作为数组而不是直接将基本类型的值传回开发人员?这就是糟糕的API构建,强制开发人员每次都使用SearchColumnField [0] .searchValue而不是SearchColumnField.searchValue!

1
哈哈,你在一个四年前的问题上发帖,我猜想这意味着他们没有做任何事情来让他们的API更容易使用!我已经不再使用NetSuite(手指交叉),但如果你现在必须使用它,我感到你的痛苦!希望我上面的帖子对你有所帮助。我会接受你的回答,因为我的问题的确似乎是“不,没有更简单的方法。” - FirstDivision

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接