Domanda

I have a datatable prdData like this

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

In this table product data is stored. Product number, product name, short description, Long description are the data stored.If the typenumber is 0 its name, if 1 its short description, and if 2 its long description. And each of these data may come in different lines if the value is long. each line can be identified by linenumber for first line it will be 0 next 2 and so on. I want to convert this DataTable to another datattable like this

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  

Can any one tell me how I can achieve this?

È stato utile?

Soluzione

You can group rows by product, and then group product's rows by their type:

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

Where helper method just orders type rows by line number and returns concatenated text

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

Output:

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

You can build new DataTable manually or with this CopyToDataTable method. You also can build Xml with Linq to 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))));

Output:

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

Or (maybe) simpler solution - instead of anonymous type usage, create custom class which can be easily serialized to xml.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top