C# 如何展平2层对象列表,并在其他属性常见的情况下求和属性

C# 如何展平2层对象列表,并在其他属性常见的情况下求和属性,c#,linq,list,object,C#,Linq,List,Object,我意识到这个问题的名称令人困惑,所以让我来解释一下我的情况 我有一个物品清单。此列表中每个用户都有一个条目。然后,每个用户都有一个类别列表,每个类别都有一个类别id和一些已经计算过的值。我需要在类别列表中展平我的对象,其中每个类别的属性都已汇总。每个用户在其列表中具有相同数量的类别,并且每个类别将出现在每个用户的列表中(换句话说,每个用户将具有相同的类别列表,计算出的属性只会不同) 我的课程是: 公共类类别{ public int categoryID{get;set;} 公共十进制分类值{ge

我意识到这个问题的名称令人困惑,所以让我来解释一下我的情况

我有一个物品清单。此列表中每个用户都有一个条目。然后,每个用户都有一个类别列表,每个类别都有一个类别id和一些已经计算过的值。我需要在类别列表中展平我的对象,其中每个类别的属性都已汇总。每个用户在其列表中具有相同数量的类别,并且每个类别将出现在每个用户的列表中(换句话说,每个用户将具有相同的类别列表,计算出的属性只会不同)

我的课程是:

公共类类别{
public int categoryID{get;set;}
公共十进制分类值{get;set;}
公共十进制分类值2{get;set;}
}
公共类用户{
公共列表类别{get;set;}
}
我需要实现的是使用Linq(或任何最有效的方法)将数据展平到一个列表中,其中类别仍按各自的ID进行划分,但categoryValue和categoryValue 2分别相加。因此,对于所有用户,每个类别的总值为2

我已尝试按如下方式执行for循环:

List categoryTotals=新列表{};
foreach(用户[0]中的类别loopCategory.类别){
类别currentCategory=新类别();
category=users.Select(x=>x.categories)。其中(y=>y.categoryID==loopCategory.categoryID))。Select(t=>new{t。。。。
}
但是t给了我linq函数,而不是我想要求和的性质

我还尝试了一种仅使用linq的类似方法,但在执行SelectMany之后,再加上GroupBy,随后的select语句不会再次公开类别列表的属性

非常感谢!

这就是你想要的吗

var groupSums = 
    from g in users.SelectMany(u => u.categories).GroupBy(c => c.categoryID)
    select new
    {
        categoryID = g.Key,
        CategoryValueSum = g.Sum(c => c.categoryValue),
        CategoryValue2Sum = g.Sum(c => c.categoryValue2),
    };
users。选择many(u=>u.categories)。GroupBy(c=>c.categoryID)
为您提供一系列
Group
对象。每个对象都有一个
Key
属性,该属性等于组的
categoryID
,还实现了
IEnumerable

整个过程为您提供了一个包含
categoryID
属性的匿名对象的平面序列,以及两个类别值之和的两个sum属性。匿名类可能会受到限制,因此,根据您对结果所做的操作,您可能需要为此编写一个新的quickie类


当然,如果您出于某种原因需要保留结果,请对结果调用
ToList()

对其进行测试,结果如下所示。您将获得分组类别列表和所需的聚合结果

    var cats = users.SelectMany(x => x.categories).GroupBy(x => x.CategoryID)
        .Select(x => new Category()
        {
            CategoryID = x.Key,
            CategoryValue = x.Sum(y => y.CategoryValue),
            CategoryValue2 = x.Sum(y => y.CategoryValue2)
        });

您可以使用LINQ
SelectMany
方法与
GroupBy

var sumList = users
    .SelectMany(u => u.categories)
    .GroupBy(c => c.categoryID)
    .Select(g => new category()
    {
       categoryID = g.Key,
       categoryValue = g.Sum(z => z.categoryValue),
       categoryValue2 = g.Sum(z => z.categoryValue2),
    })
   .ToList();

这将返回所有用户的
List
,其中包含
categoryValue
categoryValue 2
总和。

用户。选择many(u=>u.categories)
将为所有用户提供所有类别的单一平面序列。@Ed Plunkett指出。但是,我需要根据他们的ID对这一平面序列的类别进行分组,并计算每个类别的值。谢谢!工作很有魅力。看到它时非常简单,但是经过几个小时的努力(我对Linq相当陌生)我似乎不可能。我被困在为什么Group By给我一个没有id的可枚举项上,不知道需要什么键。我进一步修改了这一点(不幸的是,我无法发布实际代码)以按复杂键分组,这样我就可以得到类别名称(不包括在问题中)还有分类顺序。@eugenedlange是的,在这个
IGroupping
接口中使用GroupBy的返回类型似乎很棘手,但是如果你知道怎么做,那就很容易了。