LINQ使用C#将少数列交换到DataTable的行

我有数据表:

location Quarter ppl_required ppl_available BLR Q1 70 35 BLR Q2 50 45 BLR Q3 25 28 BLR Q4 60 58 CHN Q1 77 92 CHN Q2 42 66 CHN Q3 29 20 CHN Q4 22 24 

有没有更好的方法可以使用LINQLINQ高级function(使用.NET3.5 / 4.0 / 4.5框架)以非常简单或简短的方式[ 无循环 ]将以下DataTable作为输出。

 Location ppl_Required_Q1 ppl_Required_Q2 ppl_Required_Q3 ppl_Required_Q4 ppl_available_Q1 ppl_available_Q2 ppl_available_Q3 ppl_available_Q4 BLR 70 50 25 60 35 45 28 58 CHN 77 42 29 22 92 66 20 24 

我不确定你曾尝试过什么,如果有任何效率或灵活性需求,或者你真正需要输出容器,但也许这么简单,这很有用。 假设dt是你的数据表:

 var newSet = dt.AsEnumerable() .GroupBy(r => r.Field("Location")) .Select(g => new { Location = g.Key, ppl_required_Q1 = g.Where(p => p.Field("Quarter") == "Q1").Sum(p => p.Field("ppl_required")), ppl_required_Q2 = g.Where(p => p.Field("Quarter") == "Q2").Sum(p => p.Field("ppl_required")), ppl_required_Q3 = g.Where(p => p.Field("Quarter") == "Q3").Sum(p => p.Field("ppl_required")), ppl_required_Q4 = g.Where(p => p.Field("Quarter") == "Q4").Sum(p => p.Field("ppl_required")), ppl_available_Q1 = g.Where(p => p.Field("Quarter") == "Q1").Sum(p => p.Field("ppl_available")), ppl_available_Q2 = g.Where(p => p.Field("Quarter") == "Q2").Sum(p => p.Field("ppl_available")), ppl_available_Q3 = g.Where(p => p.Field("Quarter") == "Q3").Sum(p => p.Field("ppl_available")), ppl_available_Q4 = g.Where(p => p.Field("Quarter") == "Q4").Sum(p => p.Field("ppl_available")), }); 

编辑

添加一个扩展方法,从这里和这里的示例汇编,以防链接在将来被破坏。 您应该可以根据需要修改它。

 public static DataTable ToDataTable(this IEnumerable source, string newTableName) { DataTable newTable = new DataTable(newTableName); T firstRow = source.FirstOrDefault(); if (firstRow != null) { PropertyInfo[] properties = firstRow.GetType().GetProperties(); foreach (PropertyInfo prop in properties) { newTable.Columns.Add(prop.Name, prop.PropertyType); } foreach (T element in source) { DataRow newRow = newTable.NewRow(); foreach (PropertyInfo prop in properties) { newRow[prop.Name] = prop.GetValue(element, null); } newTable.Rows.Add(newRow); } } return newTable; } 

我创建了一个类似于你在LINQPad中描述的数据结构,这是我的代码

 void Main() { List locations = new List { new Location { Key = "BLR", Quarter = "Q1", PeopleRequired = 70, PeopleAvailable = 35 }, new Location { Key = "BLR", Quarter = "Q2", PeopleRequired = 50, PeopleAvailable = 45 }, new Location { Key = "BLR", Quarter = "Q3", PeopleRequired = 25, PeopleAvailable = 28 }, new Location { Key = "BLR", Quarter = "Q4", PeopleRequired = 60, PeopleAvailable = 58 }, new Location { Key = "CHN", Quarter = "Q1", PeopleRequired = 77, PeopleAvailable = 92 }, new Location { Key = "CHN", Quarter = "Q2", PeopleRequired = 42, PeopleAvailable = 66 }, new Location { Key = "CHN", Quarter = "Q3", PeopleRequired = 29, PeopleAvailable = 20 }, new Location { Key = "CHN", Quarter = "Q4", PeopleRequired = 22, PeopleAvailable = 24 }, new Location { Key = "CAD", Quarter = "Q1", PeopleRequired = 100, PeopleAvailable = 150 }, new Location { Key = "CAD", Quarter = "Q2", PeopleRequired = 200, PeopleAvailable = 250 }, }; var results = ( from loc in locations.Select(l => new { l.Key }).Distinct() join q1 in locations.Where(l => l.Quarter == "Q1") on loc.Key equals q1.Key into quarter1 join q2 in locations.Where(l => l.Quarter == "Q2") on loc.Key equals q2.Key into quarter2 join q3 in locations.Where(l => l.Quarter == "Q3") on loc.Key equals q3.Key into quarter3 join q4 in locations.Where(l => l.Quarter == "Q4") on loc.Key equals q4.Key into quarter4 from q1 in quarter1.DefaultIfEmpty() from q2 in quarter2.DefaultIfEmpty() from q3 in quarter3.DefaultIfEmpty() from q4 in quarter4.DefaultIfEmpty() select new { loc.Key, Q1_PeopleRequired = q1 != null ? q1.PeopleRequired : -1, Q1_PeopleAvailable = q1 != null ? q1.PeopleAvailable : -1, Q2_PeopleRequired = q2 != null ? q2.PeopleRequired : -1, Q2_PeopleAvailable = q2 != null ? q2.PeopleAvailable : -1, Q3_PeopleRequired = q3 != null ? q3.PeopleRequired : -1, Q3_PeopleAvailable = q3 != null ? q3.PeopleAvailable : -1, Q4_PeopleRequired = q4 != null ? q4.PeopleRequired : -1, Q4_PeopleAvailable = q4 != null ? q4.PeopleAvailable : -1 } ); results.Dump(); } // Define other methods and classes here public class Location { public string Key { get; set; } public string Quarter { get; set; } public int PeopleRequired { get; set; } public int PeopleAvailable { get; set; } } 

我最终得到的结果就是你要找的东西。 以上这可能是也可能不是最好的方式,我在一张大桌子上制作滞后但它有效:)

 Key | Q1_PeopleRequired | Q1_PeopleAvailable | Q2_PeopleRequired | Q2_PeopleAvailable | Q3_PeopleRequired | Q3_PeopleAvailable | Q4_PeopleRequired | Q4_PeopleAvailable ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- BLR | 70 | 35 | 50 | 45 | 25 | 28 | 60 | 58 CHN | 77 | 92 | 42 | 66 | 29 | 20 | 22 | 24 CAD | 100 | 150 | 200 | 250 | -1 | -1 | -1 | -1