Search code examples
c#linqdatagridviewmodels

How to flatten nested objects (LINQ)


I'm doing some work on an old Winforms grid and i have two Models that i am trying to flatten and assign to a DataGridView.

Here are my sample models.

public class StockItem
{
     public string StockName { get; set; }
     public int Id { get; set; }
     public List<Warehouse> Warehouses { get; set; }
}

public class Warehouse
{
     public string WarehouseName { get; set; }
     public int Id { get; set; }
}

The data works in a way that a warehouse must first be created and then assigned to each StockItem. A StockItem may have all the warehouses or may only have one.

I need to flatten the data so that the grid shows the StockName and then all the associated warehouses for the stock item.

Example

StockCode1      Warehouse1   Warehouse2   Warehouse3
StockCode2      Warehouse1   Warehouse2   
StockCode2      Warehouse1                Warehouse3   

I've attempted to do this via a Linq query but can only get a record per StockItem\Warehouse.


Solution

  • You can achieve it by creating a DataTable that yon can easily use as a source for the gridview. First add all columns and then for each stock add the warehouses:

    var warehouseNames = 
        stocks
        .SelectMany(x => x.Warehouses.Select(y => y.WarehouseName)).Distinct();
    
    var dt = new DataTable();
    dt.Columns.Add("StockCode");
    
    foreach (var name in warehouseNames)
    {
        dt.Columns.Add(name);
    }
    
    foreach (var stock in stocks)
    {
        var row = dt.NewRow();
        row["StockCode"] = stock.Id;
        foreach (var warehouse in stock.Warehouses)
        {
            row[warehouse.WarehouseName] = warehouse.Id;
        }
        dt.Rows.Add(row);
    }
    

    Warehouses