Extension Methods for Easy Data Extraction

Today I am continuing the theme of extension methods by talking about a few I primarily use for aiding in testing scenarios. Have you ever been in the situation where you are stepping through your code and get a set of data back from a SQL call and wish there was an easy way to save it so you could use it as test data? I have a few extension methods that make this situation much easier and all deal with a DataTable.

DataTable Extension Methods

public static void ToCSVFile(this DataTable dt, string fileName, char splitCharacter)
{
    File.WriteAllText(fileName, dt.ToCSVString(splitCharacter));
}
 
public static string ToCSVString(this DataTable dt, char splitCharacter)
{
    StringBuilder sb = new StringBuilder();
    string[] columnNames = dt.Columns.Cast<DataColumn>().
                                        Select(column => column.ColumnName).
                                        ToArray();
    sb.AppendLine(string.Join(",", columnNames));
    foreach (DataRow row in dt.Rows)
    {
        string[] fields = row.ItemArray.Select(field => field.ToString()).ToArray();
        sb.AppendLine(string.Join(",", fields));
    }
    return sb.ToString();
}
 
public static void FromCSVFile(this DataTable dt, string fileName, char splitCharacter)
{
    StreamReader sr = new StreamReader(fileName);
    dt.FromCSVString(sr.ReadToEnd(), splitCharacter);
}
 
public static void FromCSVString(this DataTable dt, string csvData, char splitCharacter)
{
    StringReader sr = new StringReader(csvData);
    string[] columns;
    string[] rows;
    string myStringRow = sr.ReadLine();
    columns = myStringRow.Split(splitCharacter);
 
    foreach (string column in columns)
    {
        dt.Columns.Add(column);
    }
    myStringRow = sr.ReadLine();
    while (myStringRow != null)
    {
        rows = myStringRow.Split(splitCharacter);
        dt.Rows.Add(rows);
        myStringRow = sr.ReadLine();
    }
}

Here I have four extension methods that make saving and loading a DataTable extremely easy. You can save to and read from a file or string that contains data separated by the delimiter of your choosing.

Usage

There are two ways to use these methods to save data off quickly, of course these methods can also be used for normal coding as well and not limited to the below scenarios.

  • Drop in a line of code right after you get the data back into your DataTable.
myTable.ToCSVFile(@"C:\Source\CSVTest.csv"',');
        // OR
string s = myTable.ToCSVString(',');
  • While debugging use the Immediate Window and write the same line after a break point has been hit, within scope of the DataTable, after it has been filled.

Using the Immediate Window to quickly save off data from a DataTable while stopped at a break point via Extension Methods.

Using ToCSVString and ToCSVFile from the Immediate Window is extremely useful because it does not require you to edit your code and can be used as an after though while debugging, Just In Time data extraction ;).

How is this helpful?

Once you have the data as a string or file you can use it in lots of different scenarios.

  • While stepping through code the data can be used to overwrite what is in a DataTable to try out different scenarios that may be hard to replicate.
  • You can use the string value in a unit test as part of your test setup data.
  • When using a test harness or mock you can load this data into the return variable.
  • During the exploratory phase of development simply add a line of code to load the data into a DataTable to see if what you are writing even works.

Summary

Having these extension methods handy has proven to be extremely useful in debugging, testing, and general coding. They help make life easier and development faster by saving time trying to create data sets from live scenarios and figuring out how to reuse that test data. These same ideas could easily apply to other collection types such as Lists, Arrays, and many more objects. The ability to quickly serialize data for later use is a need every developer runs into over and over again, why not keep around a few fancy extension methods to make life a little easier?

I would love to hear about any alternative methods that you use to quickly extract and save data on the spot such as when debugging. Let me know in the comments or on twitter@ScottKerlagon!