C# 根据特定条件更改数据表的结构

C# 根据特定条件更改数据表的结构,c#,datatable,ado.net,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

我有这样一个数据表
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
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  
此表中存储了产品数据。产品编号、产品名称、短描述、长描述是存储的数据。如果
typenumber
0
它的名称,如果
1
它的短描述,如果
2
它的长描述。如果值很长,这些数据中的每一个都可能出现在不同的行中。每一行都可以通过
linenumber
来识别,对于第一行,它将是
0
next
2
,依此类推。我想把这个数据表转换成另一个类似这样的数据表

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
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  

有谁能告诉我如何做到这一点吗?

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

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))
         };

您可以手动或使用此方法构建新数据表。您还可以使用Linq to 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))));
输出:

[
  {
    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"
  }
]
<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>

这是a1的名字
这是对a1的描述
这是a2的名字
a2的简短描述

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

到目前为止您尝试过什么吗?为什么需要结果作为数据表?@SergeyBerezovskiy我已经用Foreach循环尝试过了,但失败了。我的情况比这里解释的稍微复杂一点。这只是一个原型,这就是为什么我没有在这里共享代码。@SergeyBerezovskiy实际上我想要XML格式的最终结果,如果我在Datatable中解决了这个问题。对我来说,将它转换为XMLDoc很容易。谢谢你的帮助,它真的解决了我的问题。但我想知道,如果datatable中有另一列,它独立于行号和类型号,我如何在这段代码中得到它?@Athul实际上答案对于这个站点格式来说已经相当大了:)所以如果你想要这个问题的详细解决方案,最好问另一个问题。但快速解决方案如下——若您有独立的列,那个么您应该决定从该列获取数据的格式。因此,分组行将包含与产品相关的所有行,您可以为给定产品选择此字段的所有值。也可以选择聚合值