Wednesday, 8 April 2020

Convert nested Generic List to DataTable in C# and VB.Net

protected void Page_Load(object sender, EventArgs e)
{
    List<Employee> employees = new List<Employee>();
    List<EmployeeDepartments> departments = new List<EmployeeDepartments>();
 
    departments.Add(new EmployeeDepartments { Mark = 48, Department = "Physics" });
    departments.Add(new EmployeeDepartments { Mark = 45, Department = "Chemistry" });
    employees.Add(new Employee { Id = 1, Name = "John Hammond", EmployeeDetails = departments });
 
    departments = new List<EmployeeDepartments>();
    departments.Add(new EmployeeDepartments { Mark = 50, Department = "Mathmatics" });
    departments.Add(new EmployeeDepartments { Mark = 49, Department = "Biology" });
    employees.Add(new Employee { Id = 2, Name = "Mudassar Khan", EmployeeDetails = departments });
    gvEmployees.DataSource = CreateNestedDataTable<Employee, EmployeeDepartments>(employees, "EmployeeDetails");
    gvEmployees.DataBind();
}
 
public class Employee
{
    public int Id { getset; }
    public string Name { getset; }
    public List<EmployeeDepartments> EmployeeDetails { getset; }
}
 
public class EmployeeDepartments
{
    public string Department { getset; }
    public int Mark { getset; }
}
 
public DataTable CreateNestedDataTable<TOuter, TInner>(IEnumerable<TOuter> list, string innerListPropertyName)
{
    PropertyInfo[] outerProperties = typeof(TOuter).GetProperties().Where(pi => pi.Name != innerListPropertyName).ToArray();
    PropertyInfo[] innerProperties = typeof(TInner).GetProperties();
    MethodInfo innerListGetter = typeof(TOuter).GetProperty(innerListPropertyName).GetGetMethod(true);
 
    DataTable table = new DataTable();
    foreach (PropertyInfo pi in outerProperties)
    {
        table.Columns.Add(pi.Name, Nullable.GetUnderlyingType(pi.PropertyType) ?? pi.PropertyType);
    }
    foreach (PropertyInfo pi in innerProperties)
    {
        table.Columns.Add(pi.Name, Nullable.GetUnderlyingType(pi.PropertyType) ?? pi.PropertyType);
    }
 
    // iterate through outer items
    foreach (TOuter outerItem in list)
    {
        var innerList = innerListGetter.Invoke(outerItem, nullas IEnumerable<TInner>;
        if (innerList == null || innerList.Count() == 0)
        {
            // outer item has no inner items
            DataRow row = table.NewRow();
            foreach (PropertyInfo pi in outerProperties)
            {
                row[pi.Name] = pi.GetValue(outerItem, null) ?? DBNull.Value;
            }
            table.Rows.Add(row);
        }
        else
        {
            // iterate through inner items
            foreach (object innerItem in innerList)
            {
                DataRow row = table.NewRow();
                foreach (PropertyInfo pi in outerProperties)
                {
                    row[pi.Name] = pi.GetValue(outerItem, null) ?? DBNull.Value;
                }
                foreach (PropertyInfo pi in innerProperties)
                {
                    row[pi.Name] = pi.GetValue(innerItem, null) ?? DBNull.Value;
                }
                table.Rows.Add(row);
            }
        }
    }
 
    return table;
}

No comments:

Post a Comment

Table Partitioning in SQL Server

  Table Partitioning in SQL Server – Step by Step Partitioning in SQL Server task is divided into four steps: Create a File Group Add Files ...