Why Convert List to DataTable?
Here are some common scenarios where this conversion becomes necessary.
- Binding data to GridView in Web Forms.
- Exporting data to Excel or PDF.
- Passing structured data as a SqlParameter to a stored procedure (Table-Valued Parameters).
- Interoperability with legacy ADO.NET code.
Sample Class
Let’s say you have a simple class like this.
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime BirthDate { get; set; }
}
You have a list of Person.
List<Person> people = new List<Person>
{
new Person { Id = 1, Name = "Alice", BirthDate = new DateTime(1990, 1, 1) },
new Person { Id = 2, Name = "Bob", BirthDate = new DateTime(1995, 5, 23) },
new Person { Id = 3, Name = "Nic", BirthDate = new DateTime(1990, 2, 10) },
new Person { Id = 4, Name = "Jon", BirthDate = new DateTime(1994, 3, 4) }
};
You can create an extension method to convert any List<T> to a DataTable.
public static class ListToDataTableConverter
{
public static DataTable ToDataTable<T>(this List<T> items)
{
DataTable table = new DataTable(typeof(T).Name);
try
{
PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var prop in properties)
{
Type propType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
table.Columns.Add(prop.Name, propType);
}
foreach (var item in items)
{
var values = properties.Select(p => p.GetValue(item, null)).ToArray();
table.Rows.Add(values);
}
}
catch (Exception)
{
table = new DataTable();
}
return table;
}
}
Using the Method here using Blazor application.
protected override void OnInitialized()
{
DataTable dataTable = getData();
}
private DataTable getData()
{
List<Person> people = new List<Person>
{
new Person { Id = 1, Name = "Alice", BirthDate = new DateTime(1990, 1, 1) },
new Person { Id = 2, Name = "Bob", BirthDate = new DateTime(1995, 5, 23) },
new Person { Id = 3, Name = "Nic", BirthDate = new DateTime(1990, 2, 10) },
new Person { Id = 4, Name = "Jon", BirthDate = new DateTime(1994, 3, 4) }
};
DataTable dataTable = people.ToDataTable();
return dataTable;
}
Output
![Output]()
Advantages
- Generic: Works with any object type.
- Reusable: Just call.ToDataTable() on your list.
- No third-party dependencies.
Tips
- If you want only selected properties, you can modify the method to take a list of property names.
- For complex/nested properties, you'll need a recursive approach or flatten the structure.
Conclusion
This technique is a lifesaver when working with ADO.NET, reporting, or data exports in enterprise applications. By using reflection, we avoid hardcoding columns and make the method generic and reusable.