I recently had a need to create a DataSet from a List<T>, and found this post that did just that. I was happily using that in C# code, but then had a requirement to use it from a VB.Net app.
I'm not even going to attempt to hide my contempt for VB, and one of the things that I quickly tire of is typing the exact same thing multiple times. The Intellisense in VB also doesn't seem as smart as it is in C#, mainly it doesn't help as much when instantiating objects.
So I wanted a simpler way of calling the code that I had from the post above, and I immediately thought of extension methods. If I could create an extension method that made a DataSet from an IEnumerable then I could call that from the VB app with a minimal of fuss.
Kudos must go to Keith Elder for his original code, but if you want it in extension method form, then here it is:
public static class CollectionExtensions
{
public static DataSet ToDataSet<T>(this
IEnumerable<T> collection, string dataTableName)
{
if (collection == null)
{
throw new ArgumentNullException("collection");
}
if (string.IsNullOrEmpty(dataTableName))
{
throw new ArgumentNullException("dataTableName");
}
DataSet data = new DataSet("NewDataSet");
data.Tables.Add(FillDataTable(dataTableName, collection));
return data;
}
private static DataTable FillDataTable<T>(string tableName,
IEnumerable<T> collection)
{
PropertyInfo[] properties = typeof(T).GetProperties();
DataTable dt = CreateDataTable<T>(tableName,
collection, properties);
IEnumerator<T> enumerator = collection.GetEnumerator();
while (enumerator.MoveNext())
{
dt.Rows.Add(FillDataRow<T>(dt.NewRow(),
enumerator.Current, properties));
}
return dt;
}
private static DataRow FillDataRow<T>(DataRow dataRow,
T item, PropertyInfo[] properties)
{
foreach (PropertyInfo property in properties)
{
dataRow[property.Name.ToString()] = property.GetValue(item, null);
}
return dataRow;
}
private static DataTable CreateDataTable<T>(string tableName,
IEnumerable<T> collection, PropertyInfo[] properties)
{
DataTable dt = new DataTable(tableName);
foreach (PropertyInfo property in properties)
{
dt.Columns.Add(property.Name.ToString());
}
return dt;
}
}
It creates a DataSet with one table that has the name you pass in. In my case I didn't need to name the DataSet explicitly so just used a constant, but the code above could easily be updated to pass in a DataSet name if you need it.
Now you should be able to call ToDataSet on any object that implements the IEnumerable interface.