模仿通用列表上的“rollup”功能
例如,我有一个 Element
类型的通用列表。
public class Element
{
public string Country { get; set; }
public string City { get; set; }
public int Population { get; set; }
}
有以下数据。
var elements = new List<Element>
{
new Element { Country = "Country A", City = "Barrie", Population = 12 },
new Element { Country = "Country A", City = "Barrie2", Population = 12 },
new Element { Country = "Country A", City = "Barrie2", Population = 12 },
new Element { Country = "Country A", City = "Barrie", Population = 12 },
new Element { Country = "Country D", City = "Essex", Population = 12 },
new Element { Country = "Country A", City = "Barrie", Population = 12 },
new Element { Country = "Country A", City = "Barrie", Population = 12 },
new Element { Country = "Country D", City = "Essex", Population = 12 },
new Element { Country = "Country A", City = "Barrie", Population = 12 },
new Element { Country = "Country A", City = "Barrie", Population = 12 }
};
本质上,我想要按国家和城市分组的人口总数。
类似的东西。
Country A | Barrie | `running total for Barrie`
Country A | Barrie2 | `running total for Barrie2`
| | `total for Country A`
Country D | Essex | `running total for Essex`
| | `total for Country D`
| | `total for everything`
我在任何地方都找不到扩展(我说扩展是因为我计划多次使用汇总),所以我想我会尝试一下。所以我从这个简单的查询开始。
var groupedElements = elements
.GroupBy(x => new { x.Country, x.City })
.Select(x => new { Country = x.Key, City = x.Select(xx => xx.City), Population = x.Sum(xx => xx.Population) })
.ToList();
这个查询按预期工作,所以我认为我走在正确的轨道上。接下来,我想我必须弄清楚 groupedElements
中的哪个属性是聚合的,因为这就是我们要进行汇总的内容。我该如何做到这一点?或者也许我可以有一个参数,让我指定我希望在哪一列上执行聚合函数。
I have a generic list of type Element
, for example.
public class Element
{
public string Country { get; set; }
public string City { get; set; }
public int Population { get; set; }
}
With the following data.
var elements = new List<Element>
{
new Element { Country = "Country A", City = "Barrie", Population = 12 },
new Element { Country = "Country A", City = "Barrie2", Population = 12 },
new Element { Country = "Country A", City = "Barrie2", Population = 12 },
new Element { Country = "Country A", City = "Barrie", Population = 12 },
new Element { Country = "Country D", City = "Essex", Population = 12 },
new Element { Country = "Country A", City = "Barrie", Population = 12 },
new Element { Country = "Country A", City = "Barrie", Population = 12 },
new Element { Country = "Country D", City = "Essex", Population = 12 },
new Element { Country = "Country A", City = "Barrie", Population = 12 },
new Element { Country = "Country A", City = "Barrie", Population = 12 }
};
Essentially, I'd like a running total of the population grouped by country and city.
Something like.
Country A | Barrie | `running total for Barrie`
Country A | Barrie2 | `running total for Barrie2`
| | `total for Country A`
Country D | Essex | `running total for Essex`
| | `total for Country D`
| | `total for everything`
I couldn't find an extension (I say extension because I plan on using a rollup several times) anywhere so I figure I'd give it a shot. So I started with this simple query.
var groupedElements = elements
.GroupBy(x => new { x.Country, x.City })
.Select(x => new { Country = x.Key, City = x.Select(xx => xx.City), Population = x.Sum(xx => xx.Population) })
.ToList();
This query works as expected so I think I'm on the right track. Next I think I have to figure out which property from groupedElements
is aggregate because that's what we'll be doing a rollup on. How do I accomplish that? Or perhaps I could have a parameter that makes me specify what column I wish to do the aggregate function on.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为这并不像您想象的那么容易做到。首先,您想要的结果序列的项目“自然”不是同一类型。您需要每个国家/地区的运行总计、每个国家/地区的分组总计,以及总体总计。
即使您可以编写一个简洁的查询来创建此信息,调用者也必须区分结果中的每种总计。我想知道首先将您想要的结果视为单个
IEnumerable
是否有意义;创建一个像这样的好的面向对象解决方案并从那里开始可能更有意义:如果您仍然想坚持原来的想法,这是我能想到的最好的:
用法:
I don't think this is as easy to do as you might think. Firstly, the items of the result sequence you want are not 'naturally' of the same type. You want a running total within each country, grouped totals for each country, and then an overall total.
Even if you could write a terse query to create this information, the caller would have to differentiate between each kind of total from the result. I wonder if it is even makes much sense to view the result that you want as a single
IEnumerable<XXX>
in the first place; it might make much more sense to create a nice OO solution like this and proceed from there:If you still want to stick with your original idea, here's the best I can come up with:
Usage: