Dynamic PIVOT using C# Linq











up vote
0
down vote

favorite
2












I am trying to use following code to create the PIVOT but its not working.



It's giving me compile time error. I don't know linq so unable to use it.



Please help :



   DataTable Pivot(DataTable dt, DataColumn pivotColumn, DataColumn pivotValue) {
// find primary key columns
//(i.e. everything but pivot column and pivot value)
DataTable temp = dt.Copy();
temp.Columns.Remove( pivotColumn.ColumnName );
temp.Columns.Remove( pivotValue.ColumnName );
string pkColumnNames = temp.Columns.Cast(<DataColumn>)
.Select( c => c.ColumnName )
.ToArray();

// prep results table
DataTable result = temp.DefaultView.ToTable(true, pkColumnNames).Copy();
result.PrimaryKey = result.Columns.Cast(<DataColumn>).ToArray();
dt.AsEnumerable()
.Select(r =>; r[pivotColumn.ColumnName].ToString())
.Distinct().ToList()
.ForEach (c => result.Columns.Add(c, pivotColumn.DataType));

// load it
foreach( DataRow row in dt.Rows ) {
// find row to update
DataRow aggRow = result.Rows.Find(
pkColumnNames
.Select( c => row[c] )
.ToArray() );
// the aggregate used here is LATEST
// adjust the next line if you want (SUM, MAX, etc...)
aggRow[row[pivotColumn.ColumnName].ToString()] = row[pivotValue.ColumnName];
}

return result;
}


Code from : http://michaeljswart.com/2011/06/forget-about-pivot/



Moreover it tried to use following code, it works well except for it is not giving total sum for Value Column



public DataTable GetInversedDataTable(DataTable table, string columnX, string columnY, string columnZ, string nullValue, bool sumValues)
{
//Create a DataTable to Return
DataTable returnTable = new DataTable();

DataTable tempTable = table.Clone();

if (string.IsNullOrEmpty(columnX))
{
columnX = table.Columns[0].ColumnName;
}

tempTable.Columns.Remove(columnX);


//Add a Column at the beginning of the table
//returnTable.Columns.Add(columnY);

returnTable = tempTable.Clone();

//Read all DISTINCT values from columnX Column in the provided DataTale
List<string> columnXValues = new List<string>();


foreach (DataRow dr in table.Rows)
{
string columnXTemp = dr[columnX].ToString();
if (!columnXValues.Contains(columnXTemp))
{
//Read each row value, if it's different from others provided, add to the list of values and creates a new Column with its value.
columnXValues.Add(columnXTemp);
returnTable.Columns.Add(columnXTemp);
}
}

//Verify if Y and Z Axis columns re provided
if (!string.IsNullOrEmpty(columnY) && !string.IsNullOrEmpty(columnZ))
{
//Read DISTINCT Values for Y Axis Column
List<string> columnYValues = new List<string>();

foreach (DataRow dr in table.Rows)
{
if (!columnYValues.Contains(dr[columnY].ToString()))
{
columnYValues.Add(dr[columnY].ToString());
}
}

//Loop all Column Y Distinct Value
foreach (string columnYValue in columnYValues)
{
//Creates a new Row
DataRow drReturn = returnTable.NewRow();
drReturn[0] = columnYValue;
//foreach column Y value, The rows are selected distincted
DataRow rows = table.Select((columnY + "='") + columnYValue + "'");

//Read each row to fill the DataTable
foreach (DataRow dr in rows)
{
string rowColumnTitle = dr[columnX].ToString();

//Read each column to fill the DataTable
foreach (DataColumn dc in returnTable.Columns)
{
if (dc.ColumnName == rowColumnTitle)
{
//If Sum of Values is True it try to perform a Sum
//If sum is not possible due to value types, the value displayed is the last one read
if (sumValues)
{
try
{
drReturn[rowColumnTitle] = Convert.ToDecimal(drReturn[rowColumnTitle]) + Convert.ToDecimal(dr[columnZ]);
}
catch
{
drReturn[rowColumnTitle] = dr[columnZ];
}
}
else
{
drReturn[rowColumnTitle] = dr[columnZ];

}
}
}
}

returnTable.Rows.Add(drReturn);

}
}
else
{
throw new Exception("The columns to perform inversion are not provided");
}

//if a nullValue is provided, fill the datable with it
if (!string.IsNullOrEmpty(nullValue))
{
foreach (DataRow dr in returnTable.Rows)
{
foreach (DataColumn dc in returnTable.Columns)
{
if (string.IsNullOrEmpty(dr[dc.ColumnName].ToString()))
{
dr[dc.ColumnName] = nullValue;
}
}
}
}

return returnTable;
}

GetInversedDataTable(dtNormal, "Dated", "OrderStatus", "Qty", " ", true);


Please help :)










share|improve this question


























    up vote
    0
    down vote

    favorite
    2












    I am trying to use following code to create the PIVOT but its not working.



    It's giving me compile time error. I don't know linq so unable to use it.



    Please help :



       DataTable Pivot(DataTable dt, DataColumn pivotColumn, DataColumn pivotValue) {
    // find primary key columns
    //(i.e. everything but pivot column and pivot value)
    DataTable temp = dt.Copy();
    temp.Columns.Remove( pivotColumn.ColumnName );
    temp.Columns.Remove( pivotValue.ColumnName );
    string pkColumnNames = temp.Columns.Cast(<DataColumn>)
    .Select( c => c.ColumnName )
    .ToArray();

    // prep results table
    DataTable result = temp.DefaultView.ToTable(true, pkColumnNames).Copy();
    result.PrimaryKey = result.Columns.Cast(<DataColumn>).ToArray();
    dt.AsEnumerable()
    .Select(r =>; r[pivotColumn.ColumnName].ToString())
    .Distinct().ToList()
    .ForEach (c => result.Columns.Add(c, pivotColumn.DataType));

    // load it
    foreach( DataRow row in dt.Rows ) {
    // find row to update
    DataRow aggRow = result.Rows.Find(
    pkColumnNames
    .Select( c => row[c] )
    .ToArray() );
    // the aggregate used here is LATEST
    // adjust the next line if you want (SUM, MAX, etc...)
    aggRow[row[pivotColumn.ColumnName].ToString()] = row[pivotValue.ColumnName];
    }

    return result;
    }


    Code from : http://michaeljswart.com/2011/06/forget-about-pivot/



    Moreover it tried to use following code, it works well except for it is not giving total sum for Value Column



    public DataTable GetInversedDataTable(DataTable table, string columnX, string columnY, string columnZ, string nullValue, bool sumValues)
    {
    //Create a DataTable to Return
    DataTable returnTable = new DataTable();

    DataTable tempTable = table.Clone();

    if (string.IsNullOrEmpty(columnX))
    {
    columnX = table.Columns[0].ColumnName;
    }

    tempTable.Columns.Remove(columnX);


    //Add a Column at the beginning of the table
    //returnTable.Columns.Add(columnY);

    returnTable = tempTable.Clone();

    //Read all DISTINCT values from columnX Column in the provided DataTale
    List<string> columnXValues = new List<string>();


    foreach (DataRow dr in table.Rows)
    {
    string columnXTemp = dr[columnX].ToString();
    if (!columnXValues.Contains(columnXTemp))
    {
    //Read each row value, if it's different from others provided, add to the list of values and creates a new Column with its value.
    columnXValues.Add(columnXTemp);
    returnTable.Columns.Add(columnXTemp);
    }
    }

    //Verify if Y and Z Axis columns re provided
    if (!string.IsNullOrEmpty(columnY) && !string.IsNullOrEmpty(columnZ))
    {
    //Read DISTINCT Values for Y Axis Column
    List<string> columnYValues = new List<string>();

    foreach (DataRow dr in table.Rows)
    {
    if (!columnYValues.Contains(dr[columnY].ToString()))
    {
    columnYValues.Add(dr[columnY].ToString());
    }
    }

    //Loop all Column Y Distinct Value
    foreach (string columnYValue in columnYValues)
    {
    //Creates a new Row
    DataRow drReturn = returnTable.NewRow();
    drReturn[0] = columnYValue;
    //foreach column Y value, The rows are selected distincted
    DataRow rows = table.Select((columnY + "='") + columnYValue + "'");

    //Read each row to fill the DataTable
    foreach (DataRow dr in rows)
    {
    string rowColumnTitle = dr[columnX].ToString();

    //Read each column to fill the DataTable
    foreach (DataColumn dc in returnTable.Columns)
    {
    if (dc.ColumnName == rowColumnTitle)
    {
    //If Sum of Values is True it try to perform a Sum
    //If sum is not possible due to value types, the value displayed is the last one read
    if (sumValues)
    {
    try
    {
    drReturn[rowColumnTitle] = Convert.ToDecimal(drReturn[rowColumnTitle]) + Convert.ToDecimal(dr[columnZ]);
    }
    catch
    {
    drReturn[rowColumnTitle] = dr[columnZ];
    }
    }
    else
    {
    drReturn[rowColumnTitle] = dr[columnZ];

    }
    }
    }
    }

    returnTable.Rows.Add(drReturn);

    }
    }
    else
    {
    throw new Exception("The columns to perform inversion are not provided");
    }

    //if a nullValue is provided, fill the datable with it
    if (!string.IsNullOrEmpty(nullValue))
    {
    foreach (DataRow dr in returnTable.Rows)
    {
    foreach (DataColumn dc in returnTable.Columns)
    {
    if (string.IsNullOrEmpty(dr[dc.ColumnName].ToString()))
    {
    dr[dc.ColumnName] = nullValue;
    }
    }
    }
    }

    return returnTable;
    }

    GetInversedDataTable(dtNormal, "Dated", "OrderStatus", "Qty", " ", true);


    Please help :)










    share|improve this question
























      up vote
      0
      down vote

      favorite
      2









      up vote
      0
      down vote

      favorite
      2






      2





      I am trying to use following code to create the PIVOT but its not working.



      It's giving me compile time error. I don't know linq so unable to use it.



      Please help :



         DataTable Pivot(DataTable dt, DataColumn pivotColumn, DataColumn pivotValue) {
      // find primary key columns
      //(i.e. everything but pivot column and pivot value)
      DataTable temp = dt.Copy();
      temp.Columns.Remove( pivotColumn.ColumnName );
      temp.Columns.Remove( pivotValue.ColumnName );
      string pkColumnNames = temp.Columns.Cast(<DataColumn>)
      .Select( c => c.ColumnName )
      .ToArray();

      // prep results table
      DataTable result = temp.DefaultView.ToTable(true, pkColumnNames).Copy();
      result.PrimaryKey = result.Columns.Cast(<DataColumn>).ToArray();
      dt.AsEnumerable()
      .Select(r =>; r[pivotColumn.ColumnName].ToString())
      .Distinct().ToList()
      .ForEach (c => result.Columns.Add(c, pivotColumn.DataType));

      // load it
      foreach( DataRow row in dt.Rows ) {
      // find row to update
      DataRow aggRow = result.Rows.Find(
      pkColumnNames
      .Select( c => row[c] )
      .ToArray() );
      // the aggregate used here is LATEST
      // adjust the next line if you want (SUM, MAX, etc...)
      aggRow[row[pivotColumn.ColumnName].ToString()] = row[pivotValue.ColumnName];
      }

      return result;
      }


      Code from : http://michaeljswart.com/2011/06/forget-about-pivot/



      Moreover it tried to use following code, it works well except for it is not giving total sum for Value Column



      public DataTable GetInversedDataTable(DataTable table, string columnX, string columnY, string columnZ, string nullValue, bool sumValues)
      {
      //Create a DataTable to Return
      DataTable returnTable = new DataTable();

      DataTable tempTable = table.Clone();

      if (string.IsNullOrEmpty(columnX))
      {
      columnX = table.Columns[0].ColumnName;
      }

      tempTable.Columns.Remove(columnX);


      //Add a Column at the beginning of the table
      //returnTable.Columns.Add(columnY);

      returnTable = tempTable.Clone();

      //Read all DISTINCT values from columnX Column in the provided DataTale
      List<string> columnXValues = new List<string>();


      foreach (DataRow dr in table.Rows)
      {
      string columnXTemp = dr[columnX].ToString();
      if (!columnXValues.Contains(columnXTemp))
      {
      //Read each row value, if it's different from others provided, add to the list of values and creates a new Column with its value.
      columnXValues.Add(columnXTemp);
      returnTable.Columns.Add(columnXTemp);
      }
      }

      //Verify if Y and Z Axis columns re provided
      if (!string.IsNullOrEmpty(columnY) && !string.IsNullOrEmpty(columnZ))
      {
      //Read DISTINCT Values for Y Axis Column
      List<string> columnYValues = new List<string>();

      foreach (DataRow dr in table.Rows)
      {
      if (!columnYValues.Contains(dr[columnY].ToString()))
      {
      columnYValues.Add(dr[columnY].ToString());
      }
      }

      //Loop all Column Y Distinct Value
      foreach (string columnYValue in columnYValues)
      {
      //Creates a new Row
      DataRow drReturn = returnTable.NewRow();
      drReturn[0] = columnYValue;
      //foreach column Y value, The rows are selected distincted
      DataRow rows = table.Select((columnY + "='") + columnYValue + "'");

      //Read each row to fill the DataTable
      foreach (DataRow dr in rows)
      {
      string rowColumnTitle = dr[columnX].ToString();

      //Read each column to fill the DataTable
      foreach (DataColumn dc in returnTable.Columns)
      {
      if (dc.ColumnName == rowColumnTitle)
      {
      //If Sum of Values is True it try to perform a Sum
      //If sum is not possible due to value types, the value displayed is the last one read
      if (sumValues)
      {
      try
      {
      drReturn[rowColumnTitle] = Convert.ToDecimal(drReturn[rowColumnTitle]) + Convert.ToDecimal(dr[columnZ]);
      }
      catch
      {
      drReturn[rowColumnTitle] = dr[columnZ];
      }
      }
      else
      {
      drReturn[rowColumnTitle] = dr[columnZ];

      }
      }
      }
      }

      returnTable.Rows.Add(drReturn);

      }
      }
      else
      {
      throw new Exception("The columns to perform inversion are not provided");
      }

      //if a nullValue is provided, fill the datable with it
      if (!string.IsNullOrEmpty(nullValue))
      {
      foreach (DataRow dr in returnTable.Rows)
      {
      foreach (DataColumn dc in returnTable.Columns)
      {
      if (string.IsNullOrEmpty(dr[dc.ColumnName].ToString()))
      {
      dr[dc.ColumnName] = nullValue;
      }
      }
      }
      }

      return returnTable;
      }

      GetInversedDataTable(dtNormal, "Dated", "OrderStatus", "Qty", " ", true);


      Please help :)










      share|improve this question













      I am trying to use following code to create the PIVOT but its not working.



      It's giving me compile time error. I don't know linq so unable to use it.



      Please help :



         DataTable Pivot(DataTable dt, DataColumn pivotColumn, DataColumn pivotValue) {
      // find primary key columns
      //(i.e. everything but pivot column and pivot value)
      DataTable temp = dt.Copy();
      temp.Columns.Remove( pivotColumn.ColumnName );
      temp.Columns.Remove( pivotValue.ColumnName );
      string pkColumnNames = temp.Columns.Cast(<DataColumn>)
      .Select( c => c.ColumnName )
      .ToArray();

      // prep results table
      DataTable result = temp.DefaultView.ToTable(true, pkColumnNames).Copy();
      result.PrimaryKey = result.Columns.Cast(<DataColumn>).ToArray();
      dt.AsEnumerable()
      .Select(r =>; r[pivotColumn.ColumnName].ToString())
      .Distinct().ToList()
      .ForEach (c => result.Columns.Add(c, pivotColumn.DataType));

      // load it
      foreach( DataRow row in dt.Rows ) {
      // find row to update
      DataRow aggRow = result.Rows.Find(
      pkColumnNames
      .Select( c => row[c] )
      .ToArray() );
      // the aggregate used here is LATEST
      // adjust the next line if you want (SUM, MAX, etc...)
      aggRow[row[pivotColumn.ColumnName].ToString()] = row[pivotValue.ColumnName];
      }

      return result;
      }


      Code from : http://michaeljswart.com/2011/06/forget-about-pivot/



      Moreover it tried to use following code, it works well except for it is not giving total sum for Value Column



      public DataTable GetInversedDataTable(DataTable table, string columnX, string columnY, string columnZ, string nullValue, bool sumValues)
      {
      //Create a DataTable to Return
      DataTable returnTable = new DataTable();

      DataTable tempTable = table.Clone();

      if (string.IsNullOrEmpty(columnX))
      {
      columnX = table.Columns[0].ColumnName;
      }

      tempTable.Columns.Remove(columnX);


      //Add a Column at the beginning of the table
      //returnTable.Columns.Add(columnY);

      returnTable = tempTable.Clone();

      //Read all DISTINCT values from columnX Column in the provided DataTale
      List<string> columnXValues = new List<string>();


      foreach (DataRow dr in table.Rows)
      {
      string columnXTemp = dr[columnX].ToString();
      if (!columnXValues.Contains(columnXTemp))
      {
      //Read each row value, if it's different from others provided, add to the list of values and creates a new Column with its value.
      columnXValues.Add(columnXTemp);
      returnTable.Columns.Add(columnXTemp);
      }
      }

      //Verify if Y and Z Axis columns re provided
      if (!string.IsNullOrEmpty(columnY) && !string.IsNullOrEmpty(columnZ))
      {
      //Read DISTINCT Values for Y Axis Column
      List<string> columnYValues = new List<string>();

      foreach (DataRow dr in table.Rows)
      {
      if (!columnYValues.Contains(dr[columnY].ToString()))
      {
      columnYValues.Add(dr[columnY].ToString());
      }
      }

      //Loop all Column Y Distinct Value
      foreach (string columnYValue in columnYValues)
      {
      //Creates a new Row
      DataRow drReturn = returnTable.NewRow();
      drReturn[0] = columnYValue;
      //foreach column Y value, The rows are selected distincted
      DataRow rows = table.Select((columnY + "='") + columnYValue + "'");

      //Read each row to fill the DataTable
      foreach (DataRow dr in rows)
      {
      string rowColumnTitle = dr[columnX].ToString();

      //Read each column to fill the DataTable
      foreach (DataColumn dc in returnTable.Columns)
      {
      if (dc.ColumnName == rowColumnTitle)
      {
      //If Sum of Values is True it try to perform a Sum
      //If sum is not possible due to value types, the value displayed is the last one read
      if (sumValues)
      {
      try
      {
      drReturn[rowColumnTitle] = Convert.ToDecimal(drReturn[rowColumnTitle]) + Convert.ToDecimal(dr[columnZ]);
      }
      catch
      {
      drReturn[rowColumnTitle] = dr[columnZ];
      }
      }
      else
      {
      drReturn[rowColumnTitle] = dr[columnZ];

      }
      }
      }
      }

      returnTable.Rows.Add(drReturn);

      }
      }
      else
      {
      throw new Exception("The columns to perform inversion are not provided");
      }

      //if a nullValue is provided, fill the datable with it
      if (!string.IsNullOrEmpty(nullValue))
      {
      foreach (DataRow dr in returnTable.Rows)
      {
      foreach (DataColumn dc in returnTable.Columns)
      {
      if (string.IsNullOrEmpty(dr[dc.ColumnName].ToString()))
      {
      dr[dc.ColumnName] = nullValue;
      }
      }
      }
      }

      return returnTable;
      }

      GetInversedDataTable(dtNormal, "Dated", "OrderStatus", "Qty", " ", true);


      Please help :)







      linq c#-4.0






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Oct 12 '12 at 20:33









      Nikhil Gupta

      3532326




      3532326
























          2 Answers
          2






          active

          oldest

          votes

















          up vote
          3
          down vote



          accepted










          Here is the code with the compilation errors corrected:



          DataTable Pivot(DataTable dt, DataColumn pivotColumn, DataColumn pivotValue) {
          // find primary key columns
          //(i.e. everything but pivot column and pivot value)
          DataTable temp = dt.Copy();
          temp.Columns.Remove( pivotColumn.ColumnName );
          temp.Columns.Remove( pivotValue.ColumnName );
          string pkColumnNames = temp.Columns.Cast<DataColumn>()
          .Select( c => c.ColumnName )
          .ToArray();

          // prep results table
          DataTable result = temp.DefaultView.ToTable(true, pkColumnNames).Copy();
          result.PrimaryKey = result.Columns.Cast<DataColumn>().ToArray();
          dt.AsEnumerable()
          .Select(r => r[pivotColumn.ColumnName].ToString())
          .Distinct().ToList()
          .ForEach (c => result.Columns.Add(c, pivotColumn.DataType));

          // load it
          foreach( DataRow row in dt.Rows ) {
          // find row to update
          DataRow aggRow = result.Rows.Find(
          pkColumnNames
          .Select( c => row[c] )
          .ToArray() );
          // the aggregate used here is LATEST
          // adjust the next line if you want (SUM, MAX, etc...)
          aggRow[row[pivotColumn.ColumnName].ToString()] = row[pivotValue.ColumnName];
          }

          return result;
          }


          I changed Cast(<DataColumn>) to Cast<DataColumn>() in two locations and got rid of the semicolon in the middle of a lambda expression. The second part of your question is a little trickier. You may want to ask it as its own question.






          share|improve this answer





















          • Thanks........... :)
            – Nikhil Gupta
            Oct 13 '12 at 6:46










          • @RiskyMartin Just found this question... I fixed the code on my blog.
            – Michael J Swart
            Dec 5 '13 at 4:34










          • @RiskyMartin, does this code actually work I I tried this and get errors on the following temp.Columns.Remove( pivotValue.ColumnName ); for example it works for the most part but not what and or how I would have expected.. for example if I want to have a DataTime which has 31 days for example be the column names.. it adds them to the end of the existing datatable.I will try this code and see if it's been updated from Michael J Stewart blog being this is where the code came from
            – MethodMan
            Feb 16 '16 at 16:47










          • @MethodMan I only fixed the compilation errors, so there could still be semantic errors. You might want to ask a separate question for this. And if you find a fix, please inform me (so I can update my answer) and the blog writer.
            – Risky Martin
            Mar 31 '16 at 23:02


















          up vote
          1
          down vote













          Good one., but you might want to replace the below line



           .ForEach (c => result.Columns.Add(c, pivotColumn.DataType));


          with this (change pivotColumn to pivotValue)



           .ForEach (c => result.Columns.Add(c, pivotValue.DataType));


          Works perfectly for my requirement.






          share|improve this answer



















          • 2




            While this code may answer the question, it would be better to include some context, explain how it works, and describe when to use it. Code-only answers are not useful in the long run.
            – ryanyuyu
            Aug 26 '15 at 18:54










          • isn't there a chance that pivotValue.DataType can return DBNull
            – Surya Pratap
            Nov 8 at 5:44











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f12866685%2fdynamic-pivot-using-c-sharp-linq%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          3
          down vote



          accepted










          Here is the code with the compilation errors corrected:



          DataTable Pivot(DataTable dt, DataColumn pivotColumn, DataColumn pivotValue) {
          // find primary key columns
          //(i.e. everything but pivot column and pivot value)
          DataTable temp = dt.Copy();
          temp.Columns.Remove( pivotColumn.ColumnName );
          temp.Columns.Remove( pivotValue.ColumnName );
          string pkColumnNames = temp.Columns.Cast<DataColumn>()
          .Select( c => c.ColumnName )
          .ToArray();

          // prep results table
          DataTable result = temp.DefaultView.ToTable(true, pkColumnNames).Copy();
          result.PrimaryKey = result.Columns.Cast<DataColumn>().ToArray();
          dt.AsEnumerable()
          .Select(r => r[pivotColumn.ColumnName].ToString())
          .Distinct().ToList()
          .ForEach (c => result.Columns.Add(c, pivotColumn.DataType));

          // load it
          foreach( DataRow row in dt.Rows ) {
          // find row to update
          DataRow aggRow = result.Rows.Find(
          pkColumnNames
          .Select( c => row[c] )
          .ToArray() );
          // the aggregate used here is LATEST
          // adjust the next line if you want (SUM, MAX, etc...)
          aggRow[row[pivotColumn.ColumnName].ToString()] = row[pivotValue.ColumnName];
          }

          return result;
          }


          I changed Cast(<DataColumn>) to Cast<DataColumn>() in two locations and got rid of the semicolon in the middle of a lambda expression. The second part of your question is a little trickier. You may want to ask it as its own question.






          share|improve this answer





















          • Thanks........... :)
            – Nikhil Gupta
            Oct 13 '12 at 6:46










          • @RiskyMartin Just found this question... I fixed the code on my blog.
            – Michael J Swart
            Dec 5 '13 at 4:34










          • @RiskyMartin, does this code actually work I I tried this and get errors on the following temp.Columns.Remove( pivotValue.ColumnName ); for example it works for the most part but not what and or how I would have expected.. for example if I want to have a DataTime which has 31 days for example be the column names.. it adds them to the end of the existing datatable.I will try this code and see if it's been updated from Michael J Stewart blog being this is where the code came from
            – MethodMan
            Feb 16 '16 at 16:47










          • @MethodMan I only fixed the compilation errors, so there could still be semantic errors. You might want to ask a separate question for this. And if you find a fix, please inform me (so I can update my answer) and the blog writer.
            – Risky Martin
            Mar 31 '16 at 23:02















          up vote
          3
          down vote



          accepted










          Here is the code with the compilation errors corrected:



          DataTable Pivot(DataTable dt, DataColumn pivotColumn, DataColumn pivotValue) {
          // find primary key columns
          //(i.e. everything but pivot column and pivot value)
          DataTable temp = dt.Copy();
          temp.Columns.Remove( pivotColumn.ColumnName );
          temp.Columns.Remove( pivotValue.ColumnName );
          string pkColumnNames = temp.Columns.Cast<DataColumn>()
          .Select( c => c.ColumnName )
          .ToArray();

          // prep results table
          DataTable result = temp.DefaultView.ToTable(true, pkColumnNames).Copy();
          result.PrimaryKey = result.Columns.Cast<DataColumn>().ToArray();
          dt.AsEnumerable()
          .Select(r => r[pivotColumn.ColumnName].ToString())
          .Distinct().ToList()
          .ForEach (c => result.Columns.Add(c, pivotColumn.DataType));

          // load it
          foreach( DataRow row in dt.Rows ) {
          // find row to update
          DataRow aggRow = result.Rows.Find(
          pkColumnNames
          .Select( c => row[c] )
          .ToArray() );
          // the aggregate used here is LATEST
          // adjust the next line if you want (SUM, MAX, etc...)
          aggRow[row[pivotColumn.ColumnName].ToString()] = row[pivotValue.ColumnName];
          }

          return result;
          }


          I changed Cast(<DataColumn>) to Cast<DataColumn>() in two locations and got rid of the semicolon in the middle of a lambda expression. The second part of your question is a little trickier. You may want to ask it as its own question.






          share|improve this answer





















          • Thanks........... :)
            – Nikhil Gupta
            Oct 13 '12 at 6:46










          • @RiskyMartin Just found this question... I fixed the code on my blog.
            – Michael J Swart
            Dec 5 '13 at 4:34










          • @RiskyMartin, does this code actually work I I tried this and get errors on the following temp.Columns.Remove( pivotValue.ColumnName ); for example it works for the most part but not what and or how I would have expected.. for example if I want to have a DataTime which has 31 days for example be the column names.. it adds them to the end of the existing datatable.I will try this code and see if it's been updated from Michael J Stewart blog being this is where the code came from
            – MethodMan
            Feb 16 '16 at 16:47










          • @MethodMan I only fixed the compilation errors, so there could still be semantic errors. You might want to ask a separate question for this. And if you find a fix, please inform me (so I can update my answer) and the blog writer.
            – Risky Martin
            Mar 31 '16 at 23:02













          up vote
          3
          down vote



          accepted







          up vote
          3
          down vote



          accepted






          Here is the code with the compilation errors corrected:



          DataTable Pivot(DataTable dt, DataColumn pivotColumn, DataColumn pivotValue) {
          // find primary key columns
          //(i.e. everything but pivot column and pivot value)
          DataTable temp = dt.Copy();
          temp.Columns.Remove( pivotColumn.ColumnName );
          temp.Columns.Remove( pivotValue.ColumnName );
          string pkColumnNames = temp.Columns.Cast<DataColumn>()
          .Select( c => c.ColumnName )
          .ToArray();

          // prep results table
          DataTable result = temp.DefaultView.ToTable(true, pkColumnNames).Copy();
          result.PrimaryKey = result.Columns.Cast<DataColumn>().ToArray();
          dt.AsEnumerable()
          .Select(r => r[pivotColumn.ColumnName].ToString())
          .Distinct().ToList()
          .ForEach (c => result.Columns.Add(c, pivotColumn.DataType));

          // load it
          foreach( DataRow row in dt.Rows ) {
          // find row to update
          DataRow aggRow = result.Rows.Find(
          pkColumnNames
          .Select( c => row[c] )
          .ToArray() );
          // the aggregate used here is LATEST
          // adjust the next line if you want (SUM, MAX, etc...)
          aggRow[row[pivotColumn.ColumnName].ToString()] = row[pivotValue.ColumnName];
          }

          return result;
          }


          I changed Cast(<DataColumn>) to Cast<DataColumn>() in two locations and got rid of the semicolon in the middle of a lambda expression. The second part of your question is a little trickier. You may want to ask it as its own question.






          share|improve this answer












          Here is the code with the compilation errors corrected:



          DataTable Pivot(DataTable dt, DataColumn pivotColumn, DataColumn pivotValue) {
          // find primary key columns
          //(i.e. everything but pivot column and pivot value)
          DataTable temp = dt.Copy();
          temp.Columns.Remove( pivotColumn.ColumnName );
          temp.Columns.Remove( pivotValue.ColumnName );
          string pkColumnNames = temp.Columns.Cast<DataColumn>()
          .Select( c => c.ColumnName )
          .ToArray();

          // prep results table
          DataTable result = temp.DefaultView.ToTable(true, pkColumnNames).Copy();
          result.PrimaryKey = result.Columns.Cast<DataColumn>().ToArray();
          dt.AsEnumerable()
          .Select(r => r[pivotColumn.ColumnName].ToString())
          .Distinct().ToList()
          .ForEach (c => result.Columns.Add(c, pivotColumn.DataType));

          // load it
          foreach( DataRow row in dt.Rows ) {
          // find row to update
          DataRow aggRow = result.Rows.Find(
          pkColumnNames
          .Select( c => row[c] )
          .ToArray() );
          // the aggregate used here is LATEST
          // adjust the next line if you want (SUM, MAX, etc...)
          aggRow[row[pivotColumn.ColumnName].ToString()] = row[pivotValue.ColumnName];
          }

          return result;
          }


          I changed Cast(<DataColumn>) to Cast<DataColumn>() in two locations and got rid of the semicolon in the middle of a lambda expression. The second part of your question is a little trickier. You may want to ask it as its own question.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Oct 13 '12 at 3:37









          Risky Martin

          2,20621013




          2,20621013












          • Thanks........... :)
            – Nikhil Gupta
            Oct 13 '12 at 6:46










          • @RiskyMartin Just found this question... I fixed the code on my blog.
            – Michael J Swart
            Dec 5 '13 at 4:34










          • @RiskyMartin, does this code actually work I I tried this and get errors on the following temp.Columns.Remove( pivotValue.ColumnName ); for example it works for the most part but not what and or how I would have expected.. for example if I want to have a DataTime which has 31 days for example be the column names.. it adds them to the end of the existing datatable.I will try this code and see if it's been updated from Michael J Stewart blog being this is where the code came from
            – MethodMan
            Feb 16 '16 at 16:47










          • @MethodMan I only fixed the compilation errors, so there could still be semantic errors. You might want to ask a separate question for this. And if you find a fix, please inform me (so I can update my answer) and the blog writer.
            – Risky Martin
            Mar 31 '16 at 23:02


















          • Thanks........... :)
            – Nikhil Gupta
            Oct 13 '12 at 6:46










          • @RiskyMartin Just found this question... I fixed the code on my blog.
            – Michael J Swart
            Dec 5 '13 at 4:34










          • @RiskyMartin, does this code actually work I I tried this and get errors on the following temp.Columns.Remove( pivotValue.ColumnName ); for example it works for the most part but not what and or how I would have expected.. for example if I want to have a DataTime which has 31 days for example be the column names.. it adds them to the end of the existing datatable.I will try this code and see if it's been updated from Michael J Stewart blog being this is where the code came from
            – MethodMan
            Feb 16 '16 at 16:47










          • @MethodMan I only fixed the compilation errors, so there could still be semantic errors. You might want to ask a separate question for this. And if you find a fix, please inform me (so I can update my answer) and the blog writer.
            – Risky Martin
            Mar 31 '16 at 23:02
















          Thanks........... :)
          – Nikhil Gupta
          Oct 13 '12 at 6:46




          Thanks........... :)
          – Nikhil Gupta
          Oct 13 '12 at 6:46












          @RiskyMartin Just found this question... I fixed the code on my blog.
          – Michael J Swart
          Dec 5 '13 at 4:34




          @RiskyMartin Just found this question... I fixed the code on my blog.
          – Michael J Swart
          Dec 5 '13 at 4:34












          @RiskyMartin, does this code actually work I I tried this and get errors on the following temp.Columns.Remove( pivotValue.ColumnName ); for example it works for the most part but not what and or how I would have expected.. for example if I want to have a DataTime which has 31 days for example be the column names.. it adds them to the end of the existing datatable.I will try this code and see if it's been updated from Michael J Stewart blog being this is where the code came from
          – MethodMan
          Feb 16 '16 at 16:47




          @RiskyMartin, does this code actually work I I tried this and get errors on the following temp.Columns.Remove( pivotValue.ColumnName ); for example it works for the most part but not what and or how I would have expected.. for example if I want to have a DataTime which has 31 days for example be the column names.. it adds them to the end of the existing datatable.I will try this code and see if it's been updated from Michael J Stewart blog being this is where the code came from
          – MethodMan
          Feb 16 '16 at 16:47












          @MethodMan I only fixed the compilation errors, so there could still be semantic errors. You might want to ask a separate question for this. And if you find a fix, please inform me (so I can update my answer) and the blog writer.
          – Risky Martin
          Mar 31 '16 at 23:02




          @MethodMan I only fixed the compilation errors, so there could still be semantic errors. You might want to ask a separate question for this. And if you find a fix, please inform me (so I can update my answer) and the blog writer.
          – Risky Martin
          Mar 31 '16 at 23:02












          up vote
          1
          down vote













          Good one., but you might want to replace the below line



           .ForEach (c => result.Columns.Add(c, pivotColumn.DataType));


          with this (change pivotColumn to pivotValue)



           .ForEach (c => result.Columns.Add(c, pivotValue.DataType));


          Works perfectly for my requirement.






          share|improve this answer



















          • 2




            While this code may answer the question, it would be better to include some context, explain how it works, and describe when to use it. Code-only answers are not useful in the long run.
            – ryanyuyu
            Aug 26 '15 at 18:54










          • isn't there a chance that pivotValue.DataType can return DBNull
            – Surya Pratap
            Nov 8 at 5:44















          up vote
          1
          down vote













          Good one., but you might want to replace the below line



           .ForEach (c => result.Columns.Add(c, pivotColumn.DataType));


          with this (change pivotColumn to pivotValue)



           .ForEach (c => result.Columns.Add(c, pivotValue.DataType));


          Works perfectly for my requirement.






          share|improve this answer



















          • 2




            While this code may answer the question, it would be better to include some context, explain how it works, and describe when to use it. Code-only answers are not useful in the long run.
            – ryanyuyu
            Aug 26 '15 at 18:54










          • isn't there a chance that pivotValue.DataType can return DBNull
            – Surya Pratap
            Nov 8 at 5:44













          up vote
          1
          down vote










          up vote
          1
          down vote









          Good one., but you might want to replace the below line



           .ForEach (c => result.Columns.Add(c, pivotColumn.DataType));


          with this (change pivotColumn to pivotValue)



           .ForEach (c => result.Columns.Add(c, pivotValue.DataType));


          Works perfectly for my requirement.






          share|improve this answer














          Good one., but you might want to replace the below line



           .ForEach (c => result.Columns.Add(c, pivotColumn.DataType));


          with this (change pivotColumn to pivotValue)



           .ForEach (c => result.Columns.Add(c, pivotValue.DataType));


          Works perfectly for my requirement.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 15 '14 at 9:34









          CrazyCasta

          16.8k33259




          16.8k33259










          answered Jan 15 '14 at 9:13









          Raghu

          492312




          492312








          • 2




            While this code may answer the question, it would be better to include some context, explain how it works, and describe when to use it. Code-only answers are not useful in the long run.
            – ryanyuyu
            Aug 26 '15 at 18:54










          • isn't there a chance that pivotValue.DataType can return DBNull
            – Surya Pratap
            Nov 8 at 5:44














          • 2




            While this code may answer the question, it would be better to include some context, explain how it works, and describe when to use it. Code-only answers are not useful in the long run.
            – ryanyuyu
            Aug 26 '15 at 18:54










          • isn't there a chance that pivotValue.DataType can return DBNull
            – Surya Pratap
            Nov 8 at 5:44








          2




          2




          While this code may answer the question, it would be better to include some context, explain how it works, and describe when to use it. Code-only answers are not useful in the long run.
          – ryanyuyu
          Aug 26 '15 at 18:54




          While this code may answer the question, it would be better to include some context, explain how it works, and describe when to use it. Code-only answers are not useful in the long run.
          – ryanyuyu
          Aug 26 '15 at 18:54












          isn't there a chance that pivotValue.DataType can return DBNull
          – Surya Pratap
          Nov 8 at 5:44




          isn't there a chance that pivotValue.DataType can return DBNull
          – Surya Pratap
          Nov 8 at 5:44


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f12866685%2fdynamic-pivot-using-c-sharp-linq%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          How to change which sound is reproduced for terminal bell?

          Can I use Tabulator js library in my java Spring + Thymeleaf project?

          Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents