我有一个带有一些字段的Order表。我现在需要其中两个:PostalCode
和TimeSlot
。结构如下:
我需要的是一个像下面这样的结构(在C#中需要Linq查询)。
提前致谢。
答案 0 :(得分:0)
你可以沿着这些方向做点什么:
//taken from LinqPad. Dump() will not work anywhere else.
void Main()
{
var source = new List<Order> {
new Order {ZipCode = "01", TimeSlot ="A" },
new Order {ZipCode = "02", TimeSlot ="B" },
new Order {ZipCode = "01", TimeSlot ="B" },
new Order {ZipCode = "01", TimeSlot ="C" }
};
var pivotedOrders = source.GroupBy (s => s.ZipCode)
.Select(o => new {
ZipCode = o.Key,
OrdersCount = o.Count(),
A = o.Count(x => x.TimeSlot == "A"),
B = o.Count(x => x.TimeSlot == "B"),
C = o.Count(x => x.TimeSlot == "C")
})
.Dump();
}
public class Order
{
public string ZipCode {get; set; }
public string TimeSlot {get; set; }
}
结果:
答案 1 :(得分:0)
在LINQ中,您无法动态创建动态对象。您应该尝试ExpandoObject,但老实说,我没有任何经验。
我将采用的解决方案是:我将构建一个像这样的对象,而不是每个时隙都有一个属性的对象:
class PivotData
{
public string ZipCode { get; set; }
public int OrdersCount { get; set; }
public Dictionary<string, int> TimeSlots {get; set;}
}
正如您所看到的,它包含一个字符串,其中键值对为string和int:字符串是时隙的名称,int是计数。
基于此对象,您可以编写LINQ代码,如下所示:
var source = new List<Order> {
new Order {ZipCode = "01", TimeSlot ="A" },
new Order {ZipCode = "01", TimeSlot ="A" },
new Order {ZipCode = "02", TimeSlot ="B" },
new Order {ZipCode = "01", TimeSlot ="B" },
new Order {ZipCode = "01", TimeSlot ="C" }
};
var result = source
.GroupBy(s => s.ZipCode)
.Select(g => new PivotData
{
ZipCode = g.Key,
OrdersCount = g.Count(),
TimeSlots = g.GroupBy(x => x.TimeSlot).ToDictionary(x => x.Key, x => x.Count())
}).ToList();
foreach(var item in result) {
System.Console.WriteLine("ZipCode: " + item.ZipCode + " - " + "Orders count: " + item.OrdersCount);
Console.WriteLine("Time slots:");
foreach(var timeSlot in item.TimeSlots) {
System.Console.WriteLine(timeSlot.Key + " - " + timeSlot.Value);
}
Console.WriteLine("---");
}