简体   繁体   English

在ASP.net中使用组合键展平嵌套分组的Linq查询

[英]Flatten Linq query of nested groupings with combined key in ASP.net

In my database there are player-objects which do have a nationality and points. 在我的数据库中,有一些具有国籍和得分的玩家对象。

I need a possibility to nest my groupings. 我需要嵌套我的分组。 Because they are given by the client, grouping into an anonymous key seems no option here. 因为它们是由客户端提供的,所以在这里将分组成匿名密钥似乎是没有选择的。 So I have to nest them like 所以我必须像

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(/*...*/);

At the end, the Dictionary should contain the keys as string like ["USA|true"] , ["USA|false"] or ["GER|true"] with their respective elements. 最后, Dictionary应包含诸如["USA|true"]["USA|false"]["GER|true"]类的string及其各自的元素。

I guess SelectMany is the key but I don't get the point where to start from to achieve this. 我想SelectMany是关键,但是我不知道从哪里开始实现这一目标。

What about this 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());

Answering your concrete question. 回答您的具体问题。

As you mentioned, SelectMany is the key. 如您所述, SelectMany是关键。 The place in your query is right after the Select : 查询中的位置就在Select

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

It can also replace the Select (ie start right after the first GroupBy ): 它还可以替换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);

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

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