我有两个班级,Customer
和KPI
:
public class Customer : BaseModel
{
public String Code { get; set; }
...
public List<KPI> KPIs { get; set; }
}
public class KPI : BaseModel
{
public String Name { get; set; }
public int PersonalValue { get; set; }
public int RegionalValue { get; set; }
public int NationalValue { get; set; }
public String Group { get; set; }
}
我需要通过Group
属性对KPI进行分组,这样如果我的数据如下所示:
+---------------------------------+
| Name PValue RValue NValue Group |
+---------------------------------+
| Low 100 600 300 Car |
| High 900 400 700 Car |
| Low 200 300 500 Truck |
| High 800 700 500 Truck |
+---------------------------------+
在对项目进行分组后,我需要一些额外的属性:
Names: 'Low, High'
PValuePercentages: '10, 90'
RValuePercentages: '60, 40'
NValuePercentages: '30, 70'
这基本上是逗号分隔的字符串,其中包含来自分组项目的计算值。我需要将它们格式化,以便我可以使用Razor轻松地将它们插入HTML元素。
这正是我目前在Razor中正在做的事情,但是在.cs文件中,以便进行更简单的测试和调试:
foreach (var customer in customerList)
{
var groups = customer.KPIs.GroupBy(item => item.Group);
foreach (var group in groups)
{
var groupName = group.Key ?? "OTHERS";
foreach (var kpi in group)
{
var kpiName = kpi.Name;
var personalValue = kpi.PersonalValue;
var regionalValue = kpi.RegionalValue;
var nationalValue = kpi.NationalValue;
}
if(!String.IsNullOrEmpty(group.Key))
{
// This doesn't work yet
//var acuVal1 = group.AcuVal1;
//var acuVal2 = group.AcuVal2;
//var acuVal3 = group.AcuVal3;
foreach (var kpi in group)
{
var kpiName= kpi.Name;
}
}
}
}
如果我尝试通过Linq查询将组更改为
var groups = customer.KPIs.GroupBy(item => item.Group).
Select(item => new
{
item.Key,
item,
AcuVal1 = item.Sum(i => i.PersonalValue),
AcuVal2 = item.Sum(i => i.RegionalValue),
AcuVal3 = item.Sum(i => i.NationalValue)
}).ToList();
注意:在这种情况下,Sum()
不是我需要的,但出于测试目的,它可以正常运行并保持简单。
执行此操作后,行
foreach (var kpi in grupo)
给出以下错误:
foreach语句不能对类型'&lt;的变量进行操作匿名 type:string Key,IGrouping item,int AcuVal1,int AcuVal2,int AcuVal3&gt;'因为'&lt;匿名类型:string Key, IGrouping项目,int AcuVal1,int AcuVal2,int AcuVal3&gt;' 不包含'GetEnumerator'
的公共定义
我做错了什么?
答案 0 :(得分:0)
当您group by
进入项时,项是键值的IGrouping
,而组只是具有键属性和一些聚合属性以及项属性的匿名类型的集合。
考虑到所有这些,如果你想迭代一个分组的子集合,你需要迭代一个组的 .item 属性
var groups = from kpi in kpis
group kpi by kpi.Group into item
select new
{
item.Key,
item,
AcuVal1 = item.Sum(i => i.PersonalValue),
AcuVal2 = item.Sum(i => i.RegionalValue),
AcuVal3 = item.Sum(i => i.NationalValue)
};
foreach (var group in groups)
{
foreach (var kpi in group.item)
{
var kpiName = kpi.Name;
}
}
注意:我非常确定您实际上并不需要嵌套的foreach,并且您应该能够通过结果查询实现所需的结果扩展
var groups = from kpi in kpis
group kpi by kpi.Group into groupings
let names = groupings.Select(p => p.Name)
let pvalues = groupings.Select(p => p.PersonalValue)
let rvalues = groupings.Select(p => p.RegionalValue)
let nvalues = groupings.Select(p => p.NationalValue)
select new
{
Key = groupings.Key,
Names = string.Join(", ", names),
PValues = string.Join(", ", pvalues),
RValues = string.Join(", ", rvalues),
NValues = string.Join(", ", nvalues),
};