Click here to Skip to main content
15,867,330 members
Articles / Programming Languages / C#

Convert a Generic List to a Datatable

Rate me:
Please Sign up or sign in to vote.
4.33/5 (6 votes)
23 May 2010CPOL3 min read 119.7K   3.3K   29   10
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:  

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

Then we can add items to this list, as:

C#
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:

C#
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:

C#
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.

C#
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:

C#
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.

C#
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.

C#
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)


Written By
Software Developer
India India
I am a Bachelor of Engineering in Information Technology.

Comments and Discussions

 
Questionthanks Pin
guacharaca12-May-14 10:49
guacharaca12-May-14 10:49 
GeneralNice and easy to understand ..Thanks Pin
AnuSoma23-Aug-13 14:04
AnuSoma23-Aug-13 14:04 
QuestionDataset does not support System.Nullable<> Pin
andy2Much11-Aug-13 11:29
andy2Much11-Aug-13 11:29 
AnswerRe: Dataset does not support System.Nullable<> Pin
punkologist9-Apr-14 12:28
punkologist9-Apr-14 12:28 
GeneralThanks! This saved me some time! Pin
JoeCrum10-Aug-11 4:49
JoeCrum10-Aug-11 4:49 
It worked perfectly, first time. I just replaced my definitions of List<t> with ABList<t>, and now can create a DataTable which will work with my existing Winforms Excel export code. Smile | :)
GeneralGOod Pin
yuyejian8-Feb-11 19:27
yuyejian8-Feb-11 19:27 
GeneralSame Idea Pin
Craig G. Wilson24-May-10 2:02
Craig G. Wilson24-May-10 2:02 
GeneralRe: Same Idea Pin
Abhijeet Singhai24-May-10 22:54
Abhijeet Singhai24-May-10 22:54 
GeneralBindingList<T> Pin
tonyt23-May-10 5:46
tonyt23-May-10 5:46 
GeneralRe: BindingList<T> Pin
Member 1075795319-Dec-18 4:23
Member 1075795319-Dec-18 4:23 

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

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