Click here to Skip to main content
Click here to Skip to main content

Convert a Generic List to a Datatable

, 23 May 2010
Rate this:
Please Sign up or sign in to vote.
A Generic List with a feature of converting itself to a DataTable

Preface

There are several cases when we feel the need to convert a List of objects into a DataTable. There is a case where I particularly feel this need.

When we are using an object oriented approach in our web application, it is always better to bind the GridView with a generic List of objects. The sorting of the GridView becomes a problem in this case as the C# .NET Generic List class does not provide an easy sorting functionality.

Traditionally (the sorting solution for GridView in almost all the .NET articles), we sort a GridView by converting the source datatable into a DataView and binding the GridView again with the sorted DataView. This is a very easy method for GridView sorting.

So, if we are binding GridView with List of objects, we feel the need to convert it to a DataTable at the time of sorting.

Since the generic class List doesn’t provide a function to convert to DataTable, I created a class ABList which has this functionality.

Hence, one can use ABList the same way as one will use List, the only difference will be an additional function GetDataTable.

I hope now I have justified the purpose of writing this article, so we can move forward to look at the working of ABList.

Introduction

ABList is a generic class which inherits System.Generics.Collections.List. It adds a public function GetDataTable and thus extends its functionality to get a DataTable containing all the public properties as columns for the underlying class, and a row for each object in the List.

It can be used to create a List of any data type whether a reference type or value type. If the underlying type is a reference type, except String, it will have columns same as all the public properties of that class. If it is a value type, then only one column will be there called “Value”, which will store the value of the variables in List.

How to Use ABList Class

Using ABList class is as simple as using a List class. We need to define a variable by providing the underlying type we want to use with our ABList class, as:  

ABList<Product> lstP = new ABList<Product>();

Then we can add items to this list, as:

lstP.Add(new Product("a", "a"));
lstP.Add(new Product("b", "b"));
lstP.Add(new Product("c", "c"));

Just the way we do it with List.

Now, if we want our List to be converted into a DataTable, we just need to call a new function defined in ABClass:

DataTable dtPro = lstP.GetDataTable();

The ABList Class

The ABList class is inheriting a generic class List, it has only one function of its own, the GetDataTable function. Following is the way ABList has been defined:

public class ABList<T> : List<T>

Simple.

Then there is the GetDataTable function. I have not constrained the ABList for reference type or value type only. So we need to take care of both the cases while converting the List into DataTable as the underlying type can be both value or reference type.

First, we check how to get a DataTable if the underlying type is a value type (or string).

In value type, the DataTable is expected to contain the values of all the variables (items) present in List. Hence we create only one column in the DataTable named “Value”, and add a new row for each item found in the List saving its value in the row.

if (typeof(T).IsValueType || typeof(T).Equals(typeof(string)))
{
   DataColumn dc = new DataColumn("Value");
   dt.Columns.Add(dc);
   foreach (T item in this)
   {
       DataRow dr = dt.NewRow();
       dr[0] = item;

       dt.Rows.Add(dr);
   }
}

Though String is a reference type, due to its behavior we treat it as a special case and handle it as value type only.

Now, for handling reference type, we need to make use of PropertyInfo class of System.Reflection namespace.

First, we find out all the public properties of the underlying class using Reflection, as:

PropertyInfo[] piT = typeof(T).GetProperties();

So, we have all the public properties of the underlying class, now we need to create a DataTable and set column names to be property names in the array piT.

foreach (PropertyInfo pi in piT)
{
   //create a datacolumn for each property
   DataColumn dc = new DataColumn(pi.Name, pi.PropertyType);

   dt.Columns.Add(dc);
}

Then, we iterate through all the items in the List and create a row for each item saving values of properties in the corresponding columns. To get the value of a property from the object (item), we need to call the GetValue method for each property in our array of PropertyInfo piT.

for (int item = 0; item < this.Count; item++)
{
    DataRow dr = dt.NewRow();

     for (int property = 0; property < dt.Columns.Count; property++)
     {
        dr[property] = piT[property].GetValue(this[item], null);
     }

     dt.Rows.Add(dr);
}

History

  • 23rd May, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Abhijeet Singhai
Software Developer
India India
I am a Bachelor of Engineering in Information Technology.

Comments and Discussions

 
Questionthanks Pinmemberguacharaca12-May-14 10:49 
GeneralNice and easy to understand ..Thanks PinmemberAnuSoma23-Aug-13 14:04 
QuestionDataset does not support System.Nullable<> Pinmemberandy2Much11-Aug-13 11:29 
AnswerRe: Dataset does not support System.Nullable<> Pinmemberpunkologist9-Apr-14 12:28 
GeneralThanks! This saved me some time! PinmemberJoeCrum10-Aug-11 4:49 
GeneralGOod Pinmemberyuyejian8-Feb-11 19:27 
GeneralSame Idea PinmemberCraig G. Wilson24-May-10 2:02 
GeneralRe: Same Idea PinmemberAbhijeet Singhai24-May-10 22:54 
GeneralBindingList<T> Pinmembertonyt23-May-10 5:46 
You can implement sort functionality on a BindingList<T> class, that can be used by a DataGridView.   BindingList<T> wraps a generic List<T>

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 23 May 2010
Article Copyright 2010 by Abhijeet Singhai
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid