0

I created 2 lines of code to sort my DataTable. I needed to do this several times, so I then moved the 2 lines into a simple method that I would call each time I needed to sort.

However, when I call the method in order to sort my DataTable, the DataTable does not maintain the sorting. There must be something taking place here that I am not aware of and that I do not understand.

My 2 lines that work as I want them to:

private void loadData()
{
  DataTable scheduleData = new DataTable();

  /*
  code that fills the DataTable with data and creates the groupOrderBy string
  */

  scheduleData.DefaultView.Sort = "SortDate, Finish";
  scheduleData = scheduleData.DefaultView.ToTable();

  scheduleData.Columns.RemoveAt(0);  // at this point, when I view the
                                     // DataTable scheduleData, the rows are sorted correctly
}

When I view the scheduleData DataTable after the above lines run, it looks like how I want it (the rows are in the correct order).

So, I tried to move them into a method as shown below:

private void loadData()
{
  DataTable scheduleData = new DataTable();

  /*
  code that fills the DataTable with data and creates the groupOrderBy string
  */

  sortDT(scheduleData, "SortDate, Finish")

  scheduleData.Columns.RemoveAt(0);  // at this point, when I view the
                                     // DataTable scheduleData, the rows are no longer sorted
                                     // (they are back to their original positions)
}

private void sortDT(DataTable dt, string sortString)
{
  dt.DefaultView.Sort = sortString;
  dt = dt.DefaultView.ToTable();  // at this point, when I view the
                                  // DataTable dt, the rows are sorted correctly
}

During the method's execution, viewing the "dt" DataTable shows correctly sorted rows. After the method's execution, viewing the scheduleData DataTable shows rows that are not sorted.

What am I not understanding here?

I thought that maybe it had to do with the DataTable in the method ("dt") versus the scheduleData one. Perhaps I was sorting "dt", but it wasn't actually affecting the scheduleData table that I passed into the method (so I should be using a method that doesn't return void?).

So, I tried this instead of the scheduleData.Columns.RemoveAt(0); line above:

private void loadData()
{
  DataTable scheduleData = new DataTable();

  /*
  code that fills the DataTable with data and creates the groupOrderBy string
  */

  deleteColumn(scheduleData);
}

private void deleteColumn(DataTable dt)
{
  dt.Columns.RemoveAt(0);
}

That simple method works, and when the code execution resumes after calling it, the scheduleData DataTable has had its Column[0] removed.

Obviously, I'm rather new to C#/programming, so I may just be missing something very simple. I don't understand why one method that manipulates my DataTable works (the removing of a column), but another method that manipulates the DataTable does not work (the sorting).

Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
elmer007
  • 1,412
  • 14
  • 27
  • Returning void is ok because DataTable is referencetype and the changes should reflect. But i'm not that sure if .ToTable() works. Because this creates a new DataTable object. And this will be not reflected. Try to use Property .Table please. It's even better for performance. – Sebi Oct 27 '16 at 19:09

3 Answers3

3

In your sortDT method, you are reassiging the dt variable to the result of dt.DefaultView.ToTable(), thus the reference to dt changes within the method. The change of the reference doesn't get reflected outside the method. So, you basically have two options:

  1. Return the result of dt.DefaultView.ToTable() from your sortDT. (In that case I would call the method GetSortedDataTable.
  2. Pass dt as reference to the method, as stated here in the MSDN docs.

I'd prefer the first option.

M.E.
  • 2,759
  • 3
  • 24
  • 33
  • Would DefaultView.Table work? There is no new Table created. Or does this ignore the sorting? I'm not sure but i think this would be faster then create a new table. – Sebi Oct 27 '16 at 19:11
  • Hm, not quite sure, but I think `ToTable()` is required. This is also used in [this answer](http://stackoverflow.com/a/3987217/1384848). – M.E. Oct 27 '16 at 19:23
  • Ok just got some performance issues with accessing ToTable massive in a grid event. There i could change to .Table which is quite faster on heavy access. But you will be right, this will ignore the sorting i guess. – Sebi Oct 27 '16 at 19:28
  • @M.E. Thanks for this answer and the link to the MSDN documentation. I think that I understand why my code behaved differently that I expected. You mention that you would prefer the first option- any particular reason? – elmer007 Oct 27 '16 at 19:33
  • 1
    In that case this is just a matter of personal preference. In my opinion, methods with return values are easier to handle than using `ref` parameters (e.g. you can do method chaining when using return values instead of returning `void`, like `GetSortedDataTable("...").DoSomethingElse()` ) – M.E. Oct 27 '16 at 19:43
2

The problem is that you are passing a reference variable, but resetting the reference in the method. The quickest way to resolve this issue is to use the ref keyword.

private void loadData()
{
    DataTable scheduleData = new DataTable();
    sortDT(ref scheduleData, "SortDate, Finish")
    scheduleData.Columns.RemoveAt(0); 
}

private void sortDT(ref DataTable dt, string sortString)
{
    dt.DefaultView.Sort = sortString;
    dt = dt.DefaultView.ToTable();  
}

You could also have SortDt return the DataTable.

private void loadData()
{
    DataTable scheduleData = sortDT(scheduleData, "SortDate, Finish");
    scheduleData.Columns.RemoveAt(0);  
}

private DataTable sortDT(DataTable dt, string sortString)
{
    dt.DefaultView.Sort = sortString;
    return dt.DefaultView.ToTable();  
}
Paul Tsai
  • 893
  • 6
  • 16
1

You have two options either use ref or return DataTable.

private void sortDT(ref DataTable dt, string sortString)
{
    dt.DefaultView.Sort = sortString;
    dt = dt.DefaultView.ToTable();  // at this point, when I view the
                              // DataTable dt, the rows are sorted correctly
}


private DataTable sortDT(DataTable dt, string sortString)
{
    dt.DefaultView.Sort = sortString;
    return dt.DefaultView.ToTable();  
}
Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197