简体   繁体   English

如何通过动态项目对linq查询进行分组

[英]How to group linq query by dynamic items

I have a grouped linq query that groups items by category, and then the location within that category: 我有一个分组的linq查询,按类别对项目进行分组,然后是该类别中的位置:

var categories = db.Items.GroupBy(p => p.Category).
    Select(group =>
    new
    {
        name = group.Key,
        data = new List<int>()
        {
            group.Count(p => p.City == "Sydney"),
            group.Count(p => p.City == "Melbourne"),
            group.Count(p => p.City == "Brisbane"),
            group.Count(p => p.City == "Perth"),
            group.Count(p => p.City == "Canberra"),
        },
        total = group.Count()
    });

As you can see, I'm hardcoding the location to get the count for each location within a category. 正如您所看到的,我正在对位置进行硬编码以获取某个类别中每个位置的计数。 I don't want to hardcode this as the locations are stored separately in the database, is there a way I can modify the query so the counts are dynamic? 我不想硬编码这个,因为位置分别存储在数据库中,有没有办法可以修改查询以便计数是动态的? For example, for everything in db.locations? 例如,对于db.locations中的所有内容?

You can use another GroupBy. 您可以使用另一个GroupBy。

var categories = db.Items.GroupBy(p => p.Category).Select(group =>
new
{
    Name = group.Key,
    Data = group.GroupBy(g => g.City),
    Total = group.Count()
});

You can also have another anonymous type inside. 你也可以在里面有另一个匿名类型。

var categories = db.Items.GroupBy(p => p.Category).Select(group =>
new
{
    Name = group.Key,
    Data = group.GroupBy(g => g.City).Select(c => 
           new
           {
               CityName = c.Key, 
               Count = c.Count()
           }),
    Total = group.Count()
});

Here is how to use it. 以下是如何使用它。 if you are confused. 如果你感到困惑

foreach(var category in categories)
{
    var name = category.Name;
    var data = category.Data;
    var total = category.Total;

    foreach(var location in data)
    {
        var cityname = location.CityName;
        var count = location.Count;
    }
}

Note that if you want to pass this query as parameter to somewhere else, you have to use dynamic keyword instead of var . 请注意,如果要将此查询作为参数传递给其他位置,则必须使用dynamic关键字而不是var

var would be fast. var会很快。 but dynamic is slow so in that case I recommend you to write custom class for holding your data instead of using anonymous type. 但是dynamic很慢所以在这种情况下,我建议你编写自定义类来保存数据,而不是使用匿名类型。

var categories = db.Items.GroupBy(p => p.Category).
Select(group =>
new
{
    name = group.Key,
    data = new List<int>()
    {
        group.Count(p => p.City == db.locations.select(loc=>loc.ToString()).ToString()),
    },
    total = group.Count()
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM