Q:

LINQ and C# summary

I have a relational table which has parent child rows. Some of the rows have a typeId and I would like to get a summary of the total cost by the type:

The list on the left is some sample data and the list on the right is the summary result expected.
The data is in a datatable. Can anyone help me with this.
ie:

typeId = 1: Which would be calculated by: 30 (total cost of 3,2) x 5 (qty of 2,1) x 3 (qty of 1,null)

(30 x 5 x 3) = 450

typeId = 2: Which would be calculated by: 12 (total cost of 5,1) x 3 (qty of 1,null)
x 15 (total cost 4,2)  x 5 (qty of 2,1) x 3 (qty of 1,null)

(12 x 3) + (15 x 5 x 3) = 261
Here is some sample code
DataTable dt = new DataTable( "Summary" );

dt.Columns.Add( "Id", Type.GetType( "System.Int32" ) );
dt.Columns.Add( "ParentId", Type.GetType( "System.Int32" ) );
dt.Columns.Add( "Qty", Type.GetType( "System.Int32" ) );
dt.Columns.Add( "Cost", Type.GetType( "System.Decimal" ) );
dt.Columns.Add( "TotalCost", Type.GetType( "System.Decimal" ) );
dt.Columns.Add( "TypeId", Type.GetType( "System.Int32" ) );

dt.Rows.Clear();

DataRow row = dt.NewRow();
row["Id"] = 1;
row["ParentId"] = DBNull.Value;
row["Qty"] = 3;
row["Cost"] = 237.00;
row["TotalCost"] = 711.00;
row["TypeId"] = DBNull.Value;
dt.Rows.Add( row );

row = dt.NewRow();
row["Id"] = 2;
row["ParentId"] = 1;
row["Qty"] = 5;
row["Cost"] = 45.00;
row["TotalCost"] = 225.00;
row["TypeId"] = DBNull.Value;
dt.Rows.Add( row );

row = dt.NewRow();
row["Id"] = 3;
row["ParentId"] = 2;
row["Qty"] = 30;
row["Cost"] = 1.00;
row["TotalCost"] = 30.00;
row["TypeId"] = 1;
dt.Rows.Add( row );

row = dt.NewRow();
row["Id"] = 4;
row["ParentId"] = 2;
row["Qty"] = 1;
row["Cost"] = 15.00;
row["TotalCost"] = 15.00;
row["TypeId"] = 2;
dt.Rows.Add( row );

row = dt.NewRow();
row["Id"] = 5;
row["ParentId"] = 1;
row["Qty"] = 4;
row["Cost"] = 3.00;
row["TotalCost"] = 12.00;
row["TypeId"] = 2;
dt.Rows.Add( row );

A:

If I understand you correctly, you need a recursive routine which is not something I would try in pure Linq, so I would try something like this.
var summary =  
    (from r in dt.AsEnumerable()
    where r["TypeID"] != DBNull.Value  
    group r by (int) r["TypeId"] into results
    select new 
        { 
        results.Key , 
        TotalCost = results.Sum(r=> (decimal) r["TotalCost"] *  GetParentsQty(r) )
        }
    );

public int GetParentsQty(DataRow child )
{
    if (child["ParentID"] == DBNull.Value)
        return 1;

    var parent = (from row in dt.AsEnumerable() 
                  where (int) child["ParentID"] == (int) row["Id"] 
                  select row
                 ).Single();

    return (int) parent ["Qty"]  * GetParentsQty(parent);
}

