I am trying to convert a generic collection (List) to a DataTable. I found the following code to help me do this:
// Sorry about indentation
public class CollectionHelper
{
private CollectionHelper()
{
}
// this is the method I have been using
public static DataTable ConvertTo<T>(IList<T> list)
{
DataTable table = CreateTable<T>();
Type entityType = typeof(T);
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType);
foreach (T item in list)
{
DataRow row = table.NewRow();
foreach (PropertyDescriptor prop in properties)
{
row[prop.Name] = prop.GetValue(item);
}
table.Rows.Add(row);
}
return table;
}
public static DataTable CreateTable<T>()
{
Type entityType = typeof(T);
DataTable table = new DataTable(entityType.Name);
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType);
foreach (PropertyDescriptor prop in properties)
{
// HERE IS WHERE THE ERROR IS THROWN FOR NULLABLE TYPES
table.Columns.Add(prop.Name, prop.PropertyType);
}
return table;
}
}
My problem is that when I change one of the properties of MySimpleClass to a nullable type, I get the following error:
DataSet does not support System.Nullable<>.
How can I do this with Nullable properties/fields in my class?
Then presumably you'll need to lift them to the non-nullable form, using Nullable.GetUnderlyingType, and perhaps change a few null values to DbNull.Value...
Change the assignment to be:
row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
and when adding the columns to be:
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(
prop.PropertyType) ?? prop.PropertyType);
And it works. (?? is the null-coalescing operator; it uses the first operand if it is non-null, else the second operand is evaluated and used)
Well. Since DataSet does not support nullable types, you'd have to check if the property is a generic type, get the generic definition of that type and then get the argument (which is the actual type) using, perhaps, Nullable.GetUnderlyingType. If the value is null, just use DBNull.Value in the DataSet.
If Nullable.GetUnderlyingType() given your prop.PropertyType returns a not-null value, use that as the type of a column. Otherwise, use prop.PropertyType itself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With