【问题标题】:Flatten Linq query of nested groupings with combined key in ASP.net在 ASP.net 中使用组合键展平嵌套分组的 Linq 查询
【发布时间】:2017-03-27 21:09:59
【问题描述】:

在我的数据库中,有些玩家对象确实具有国籍和分数。

我需要一个嵌套我的分组的可能性。因为它们是由客户端提供的,所以在这里分组为匿名密钥似乎没有选择。 所以我必须像嵌套它们一样

Players.Where(p => p.Created <= /*some date*/)
    .GroupBy(p => p.Nationality) // group them by their nationality
    .Select(arg => new {
        arg.Key,
        Elements = arg.GroupBy(p => p.Points > 0) // group them by the ones with points and the ones without
    })
    . // here i need to flatten them by also combining the key(s) of the groupings to put them into a dictionary
    .ToDictionary(/*...*/);

最后,Dictionary 应包含 string 等键,如 ["USA|true"]["USA|false"]["GER|true"] 及其各自的元素。

我猜SelectMany 是关键,但我不知道从哪里开始实现这一点。

【问题讨论】:

    标签: c# linq group-by flatten


    【解决方案1】:

    这个solution怎么样:

    public class Player
    {
        public string Nationality {get;set;}
        public int Points {get;set;}
        public double otherProp {get;set;}
    
        //new field is added
        public string groupings {get;set;}
    }
    
    var groups = new List<Func<Player, string>>();
    groups.Add(x => x.Nationality);
    groups.Add(x => (x.Points > 0).ToString().ToLower());
    Players.ForEach(x =>
        groups.ForEach(y => x.groupings = x.groupings + (x.groupings == null ? "" : "|") + y(x))
    );
    var answer = Players.GroupBy(x => x.groupings).ToDictionary(x => x.Key, x => x.ToList());
    

    【讨论】:

    • 如问题所述 - 按匿名分组不是一种选择。 group-by 子句由用户(客户端)给定值动态构建,不能转换为匿名。例如客户端发送Player(Nation,HasPoints) 并将其转换为group-by
    • @TimSchmelter 这就是GroupBy 的构建方式。 stackoverflow.com/questions/40420025/…。因为它是从给定的字符串动态构建的,new {/*...*/}.ToString() 在这里不起作用
    【解决方案2】:

    回答您的具体问题。

    正如您所提到的,SelectMany 是关键。您查询中的位置就在Select 之后:

    .Select(...)
    .SelectMany(g1 => g1.Elements.Select(g2 => new {
        Key = g1.Key + "|" + g2.Key, Elements = g2.ToList() }))
    .ToDictionary(g => g.Key, g => g.Elements);
    

    它也可以替换Select(即在第一个GroupBy之后开始):

    .GroupBy(p => p.Nationality)
    .SelectMany(g1 => g1.GroupBy(p => p.Points > 0).Select(g2 => new {
        Key = g1.Key + "|" + g2.Key, Elements = g2.ToList() }))
    .ToDictionary(g => g.Key, g => g.Elements);
    

    【讨论】:

    • 我现在有GroupBy(p =&gt; p.Nationality + "|" + p.HasPoints),它按预期工作,因为我现在只有一个键和元素。现在的问题是,如何构建传递给 group-by 的表达式?见stackoverflow.com/questions/40420025/…
    • 我知道那个帖子(因为我把它关闭为重复),但看不到与这个帖子的关系。在这里,您要求展平提供的查询,答案也是如此。如果这不是您的问题,请发布具有确切要求的问题,否则您只是在浪费试图帮助您的人的时间。
    猜你喜欢
    • 2019-11-14
    • 1970-01-01
    • 2020-04-17
    • 1970-01-01
    • 2017-04-02
    • 2020-11-12
    • 2011-02-10
    • 1970-01-01
    • 2019-03-05
    相关资源
    最近更新 更多