linq查询中的Dynamic Group By子句

时间:2018-03-20 20:26:36

标签: asp.net linq

以下linq查询根据他们的职业对城市中的人进行分组。

然而,我能够让它发挥作用的唯一方法就是对城市进行硬编码。

每个人都有一个城市。如何修改以下查询,使其按查询中返回的所有不同城市进行分组?

profession = people
    .GroupBy(p => p.Profession).
    Select(group =>
    new
    {
        name = group.Key,
        data =
        new List<int>()
        {
            group.Count(p => p.City == "Adelaide"),
            group.Count(p => p.City == "Brisbane"),
            group.Count(p => p.City == "Canberra"),
            group.Count(p => p.City == "Darwin"),                            
            group.Count(p => p.City == "Melbourne"),                            
            group.Count(p => p.City == "Perth"),
            group.Count(p => p.City == "Sydney"),
        },
    })

即如果我的数据集是:

Person {id:1, city: "Paris" }
Person {id:2, city: "Paris" }
Person {id:3, city: "London" }

然后生成的查询将是:

    profession = people
        .GroupBy(p => p.Profession).
        Select(group =>
        new
        {
            name = group.Key,
            data =
            new List<int>()
            {
                group.Count(p => p.City == "Paris"),
                group.Count(p => p.City == "London"),

            },
        })

1 个答案:

答案 0 :(得分:0)

这会产生与硬编码列表相同的输出,但我不确定它是否符合您的要求(提示:在这方面给我们预期的输出会有很大帮助)。

它只是创建一个不同的城市列表,然后构建一个谓词delegate,用于计算每个城市的出现次数,并将该谓词添加到列表中。执行实际分组时,将使用分组结果调用列表中的每个谓词。

符号Func<IGrouping<string, Person>, int>简单地说&#34;这是一个委托,它接受IGrouping<string, Person>个对象(调用GroupBy的结果)并返回int(调用Count)&#34;。

的结果
class Program
{
    static void Main(string[] args)
    {
        var people = new List<Person>()
        {
            new Person(1, "Paris", "carpenter"),
            new Person(2, "Paris", "bricklayer"),
            new Person(3, "London", "video game critic"),
        };

        var distinctCities = people.Select(p => p.City).Distinct();
        var groupPredicates = new List<Func<IGrouping<string, Person>, int>>();

        foreach (var city in distinctCities)
        {
            groupPredicates.Add(g => g.Count(p => p.City == city));
        }

        var professions = people
            .GroupBy(p => p.Profession)
            .Select(g =>
            new
            {
                name = g.Key,
                data = groupPredicates.Select(gp => gp(g)),
            });

        foreach (var profession in professions)
        {
            Console.WriteLine(profession.name + " =>");

            foreach (var count in profession.data)
            {
                Console.WriteLine("    " + count);
            }
        }

        Console.ReadKey(true);
    }
}

struct Person
{
    public int Id { get; set; }
    public string City { get; set; }
    public string Profession { get; set; }

    public Person(int id, string city, string profession)
    {
        Id = id;
        City = city;
        Profession = profession;
    }
}
相关问题