在特定条件下更改数据表的结构

时间:2014-05-12 09:47:22

标签: c# datatable ado.net

我有像这样的数据表prdData

productid        text                    linenumber    typenumber
100              this is the                 0             2
100              description of a1           2             2 
200              this is the name of a2      0             0
100              this is the name of a1      0             0
200              shortdescription of a2      0             1

在此表中存储产品数据。产品编号,产品名称,简短描述,长描述是存储的数据。如果typenumber0的名称,1是简短描述,还是2详细描述。如果值很长,这些数据中的每一个都可能出现在不同的行中。每行可以通过linenumber标识第一行0下一个2,依此类推。我想将此DataTable转换为另一个这样的数据表

productId   name                    shortdescription             longdescription
100         this is the name of a1                               this is the description of a1 
200         this is the name of a2   shortdescription of a2  

任何人都可以告诉我如何实现这个目标吗?

1 个答案:

答案 0 :(得分:2)

您可以按产品对行进行分组,然后按类型对产品的行进行分组:

var query = from r in table.AsEnumerable()
            group r by r.Field<int>("productid") into g
            let types = g.GroupBy(r => r.Field<int>("typenumber")) 
            select new {
               productId = g.Key,
               name = GetText(types.FirstOrDefault(t => t.Key == 0)),
               shortdescription = GetText(types.FirstOrDefault(t => t.Key == 2)),
               longdescription = GetText(types.FirstOrDefault(t => t.Key == 1))
         };

其中,helper方法只是按行号排序,并返回连接文本

private static string GetText(IEnumerable<DataRow> rows)
{
    if (rows == null)
        return null;

    var query = from r in rows
                orderby r.Field<int>("linenumber")
                select r.Field<string>("text");

    return String.Join(" ", query);                   
}

输出:

[
  {
    productId: 100,
    name: "this is the name of a1",
    shortdescription: "this is the description of a1",
    longdescription: null
  },
  {
    productId: 200,
    name: "this is the name of a2",
    shortdescription: null,
    longdescription: "shortdescription of a2"
  }
]

您可以手动或使用此CopyToDataTable方法构建新的DataTable。您还可以使用Linq构建Xml到Xml:

var xdoc = new XDocument(new XElement("products",
              from p in query
              select new XElement("product",
                  new XAttribute("productId", p.productId),
                  new XElement("name", p.name),
                  new XElement("shortDescription", p.shortdescription),
                  new XElement("longDescription", p.longdescription))));

输出:

<products>
  <product productId="100">
    <name>this is the name of a1</name>
    <shortDescription>this is the description of a1</shortDescription>
    <longDescription />
  </product>
  <product productId="200">
    <name>this is the name of a2</name>
    <shortDescription />
    <longDescription>shortdescription of a2</longDescription>
  </product>
</products>

或者(可能)更简单的解决方案 - 而不是匿名类型使用,创建可以轻松序列化为xml的自定义类。