将垂直行转换为水平数据表

时间:2014-10-30 11:05:45

标签: c#

我有一个网络服务,在下面的代码中我循环浏览了一系列项目。这些项目以类似xml的方式显示(参见下面的示例)。但是我想像时尚一样在表格中显示它们。我想过使用数据表在那里插入项目,然后重新显示它们。

585344
        585344 Title Issue 1
        585344 Number 140024
        585344 State In progress
585350
        585350 Title Issue 2
        585350 Number 140026
        585350 State Classification

如何以这样的方式显示它们:

ID        |  Title             |   Number    | State         
585344       issue 1               140024      In progress

   static void Main(string[] args)
    {
        ABWebService webSvc = new ABWebService();
        GetObjectListData gold = new GetObjectListData();

        gold.folderPath = "01. ITSM - Service Operation";
        gold.RequiredField = new RequiredField[3];
        gold.RequiredField[0] = new RequiredField {Value = "Title"};
        gold.RequiredField[1] = new RequiredField {Value = "Number"};
        gold.RequiredField[2] = new RequiredField {Value = "State"};

        try
        {
            GetObjectListResult golr = webSvc.GetObjectList(gold);

            List<NewsTracker> list = new List<NewsTracker>();
            if (golr.success)
            {
                ObjectData[] myObjects = golr.Object;
                for (int i = 0; i < myObjects.Length; i++)
                {
                    Console.WriteLine(myObjects[i].id);
                    foreach (object myItem in myObjects[i].Items)
                    {
                        string field1 = string.Empty;
                        string val1 = string.Empty;
                        int val2 = 0;
                        string field2 = string.Empty;

                        StringVal item = myItem as StringVal;
                        if (item != null)
                        {
                            field1 = item.name;
                            val1 = item.Value;
                            Console.WriteLine("\t" + myObjects[i].id + " " + field1 + " " + val1);

                        }

                        LongIntVal val = myItem as LongIntVal;
                        if (val != null)
                        {
                            field2 = val.name;
                            val2 = val.Value;
                            Console.WriteLine("\t" + myObjects[i].id + " " + field2 + " " + val2);

                        }

                    }
                }
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            throw;
        }
    }

编辑1:

你能告诉我如何将它们添加到这样的通用列表中:list.Add(new NewsTracker(title,number,state));以便我可以循环并对列表执行其他操作吗?

2 个答案:

答案 0 :(得分:2)

如果您只有简单类型,那么您可以使用反射来构建该表。这里是我经常用来将类信息发送到Web服务的方法的示例。一旦理解了逻辑

,就可以调整以接收List并创建包含多行的1个表
public static DataTable ObjectToData(object o)
{
    DataTable dt = new DataTable("OutputData");
    DataRow dr = dt.NewRow();
    dt.Rows.Add(dr);

    o.GetType().GetProperties().ToList().ForEach(f =>
    {
        try
        {
            f.GetValue(o, null);
            dt.Columns.Add(f.Name, f.PropertyType);
            dt.Rows[0][f.Name] = f.GetValue(o, null);
        }
        catch { }
    });

    return dt;
}

如果您在

下面的每个结构传递对象ClassA
ClassA
{
    string Value1 = "abc";
    DateTime Value2 = DateTime.Now();
    int Value3 = 12;    
}

ObjectToData(MyClassA);数据表将如下所示:

|----------|-------------------------|----------|
|  Value1  |          Value2         |  Value3  |
|==========|=========================|==========|
|   "abc"  |  2015/10/30 08:00:00 AM |    12    |
|----------|-------------------------|----------|

答案 1 :(得分:1)

您可以按键(示例中的ID)进行分组,并相应地填充其他值。如果你想要一个通用代码,你可以使用一些通用属性,关联“列名”和“值”,如下所示:

的伪代码:

// Consider ID as the key (maybe int in your case) and GenericProperty as a class of just 2 properties: name of property and value.
List<YourClass> list;
Dictionary<ID, HashSet<GenericProperty>> dict = ConvertToDictionary(list); // Convert the list to a dictionary
// Aggregate values per ID (key)
// You can get the PropertyName with reflection

foreach (var pair in dict)
{
    var row = DataTable.Rows.AddRow();

    foreach (var values in pair.Value)
        row[pair.Value.PropertyName] = pair.Value.Value;
}

请注意,如果您不需要通用代码,则GenericProperty类可以是具有所有值作为属性的特定类。在您的示例中,有3个属性:标题,数字,状态。然后,您可以使用它们来填充DataTable。示例如下:

另外,你可以通过反射获得属性名称和值(例如here),或者像弗兰克所说的那样。

编辑(基于问题编辑):

让我们为你展示的“myObjects”对象做一个例子。

如果我理解正确,“myObjects”已经是您的分组列表。所以“myObjects.Items”是一个分组键的值。

所以我们有:

List<NewsTracker> list = new List<NewsTracker>(myObjects.Count);
foreach (var obj in myObjects)
{
    // 'obj' is one key, so one value of NewsTracker
    NewsTracker nt = new NewsTracker();

    foreach (var item in myObjects.Items)
    {
        // Capture the name of the item and check what property is it from
        // Code you've show in your question. --> I'll consider that you already know how to get "fieldName" as with "value" (object)
        if (fieldName.Equals("Title"))
            nt.Title = (string)value;
        else if (fieldName.Equals("Number")
            nt.Number = (int)value;
        // ... and so on ...
     }
     // At the end of the inner loop, we must have a "NewsTracker" filled with the correct values, so now we only need to add them to the main list
     list.Add(nt);
}

注意:我已经为您的问题编写了一个特定的代码,考虑了'NewsTracker'类。