如何展平2层对象列表并总结其他属性常见的属性

时间:2016-09-28 16:28:20

标签: c# linq list object

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

我有一个对象列表。此列表包含每个用户的条目。然后,每个用户都有一个类别列表,每个类别都有一个类别ID,以及一些已经计算过的值。我需要在一个类别列表中展平我的对象,其中每个类别的属性已经加总。每个用户在其列表中将具有相同数量的类别,并且每个类别将出现在每个用户的列表中(换句话说,每个用户将具有相同的类别列表,计算的属性将仅不同)。

我的课程是:

public class category {
     public int categoryID { get; set; }
     public decimal categoryValue { get; set; }
     public decimal categoryValue2 { get; set; }
}

public class user {
    public List<category> categories { get; set; }
}

我需要实现的是使用Linq(或任何最有效的方法)将数据展平为单个列表,其中类别仍然按其各自的ID进行拆分,但classValue和categoryValue2已分别合计。因此,我为所有用户获得每个类别2个总计值。

我尝试过如下的for循环:

List<category> categoryTotals = new List<category> {};
foreach (category loopCategory in users[0].categories) {
    category currentCategory = new category();
    category = users.Select(x => x.categories).Where(y=>y.categoryID== loopCategory.categoryID)).Select(t => new {t....
}

但是t给了我linq函数,而不是我要求的属性。

我也尝试过使用linq的类似方法,但在执行SelectMany之后,接着是GroupBy,后续的select语句再次没有公开类别列表的属性。

非常感谢!

3 个答案:

答案 0 :(得分:2)

这是你想要的吗?

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.SelectMany(u => u.categories).GroupBy(c => c.categoryID)为您提供了一系列Group<category>个对象。每个属性都有一个Key属性,等于该组的categoryID,并且还实现了IEnumerable<category>

整个事情为您提供了一个具有categoryID属性的平面匿名对象序列,以及两个类别值之和的两个和属性。匿名类可能是限制性的,因此根据您对结果所做的操作,您可能希望为此编写一个新的quickie类。

当然,如果您因某些原因需要保留结果,请在结果上调用ToList()

答案 1 :(得分:1)

您可以使用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<category> categoryValue,并为所有用户汇总categoryValue2

答案 2 :(得分:0)

测试了它,它看起来像这样。您将获得具有所需汇总结果的分组类别列表。

    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)
        });