I’ve had an extension method that transforms an IEnumerable<T> into a DataTable. It currently processes all public instance properties of type T and adds them as columns to the DataTable
`public static DataTable ToDataTable<T>(this IEnumerable<T> items)
{
var dataTable = new DataTable("Table");
var itemType = typeof(T);
var props = itemType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
var dateTimeProperties = props.Where(p => p.PropertyType == typeof(DateTime)).ToList();
// Add all properties as columns
foreach (var prop in props)
{
dataTable.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
}
// Populate the rows
foreach (var item in items)
{
var values = props.Select(prop =>
{
var value = prop.GetValue(item, null);
// Handle DateTime formatting
if (dateTimeProperties.Contains(prop))
{
value = ((DateTime)value!).ToString("dd-MMM-yyyy");
}
return value;
}).ToArray();
dataTable.Rows.Add(values);
}
return dataTable;
}`
I’d like to extend this method to allow selective inclusion or exclusion of columns based on the user’s input. I want to introduce two parameters.
columnNames: an optional list of column names to filter by.
includeColumns: a boolean that indicates whether to include (true) or exclude (false) the columns in columnNames.
public static DataTable ToDataTable<T>(this IEnumerable<T> items, string[] columnNames, bool includ = true)
>Solution :
var filteredProps = includeColumns ? props.Where(p => columnNames == null || columnNames.Contains(p.Name)) : props.Where(p => columnNames == null || !columnNames.Contains(p.Name));
var propertyInfos = filteredProps.ToList();
//In Variable `propertyInfos` u will have now all the Filtered Properties.
foreach (var prop in propertyInfos)
{
dataTable.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
}
Method Signature:
public static DataTable ToDataTable<T>(this IEnumerable<T> items, IEnumerable<string> columnNames, bool includeColumns = true)