如何在linq中进行分组

时间:2017-06-23 09:58:26

标签: c# linq

我有一些简单的simpel循环工作,但我想知道如何使用LINQ,如果可能的话。

我甚至不知道如何描述我想做的事情。但堆栈溢出要求我用文字而不是一个例子来做,所以这就是我欺骗它......

课程(剥离)

public class Product
{

    public int ProductId { get; set; }
    public string Name { get; set; }
    public List<CategoryGroup> CategoryGroups { get; set; }
}

public class CategoryGroup
{
    public int CategoryGroupId { get; set; }
    public string Name { get; set; }
    public List<Category> Categories { get; set; }
}

public class Category
{
    public int CategoryId { get; set; }
    public string Name { get; set; }
}

我想做什么

Product 1
    CategoryGroup 1
        Category 11
        Category 12
        Category 13
    CategoryGroup 2
        Category 21
        Category 22

Product 2
    Category Group 1
        Category 11
        Category 14
    Category Group 2
        Category 21
    Category Group 3
        Category 31

Category Group 1
    Category 11
    Category 12
    Category 13
    Category 14
Category Group 2
    Category 21
    Category 22
Category Group 3
    Category 31

工作代码

var categoryGroups = new List<CategoryGroup>();
foreach (var product in products)
{
    foreach (var categoryGroup in product.CategoryGroups)
    {
        var group = categoryGroups.SingleOrDefault(cg => cg.CategoryGroupId == categoryGroup.CategoryGroupId);
        if (group == null)
        {
            group = new CategoryGroup {
                Categories = new List<Category>(),
                CategoryGroupId = categoryGroup.CategoryGroupId,
                Name = categoryGroup.Name
            };
            categoryGroups.Add(group);
        }

        foreach (var category in categoryGroup.Categories)
        {
            if (group.Categories.Any(c => c.CategoryId == category.CategoryId))
            {
                continue;
            }
            group.Categories.Add(category);
        }
    }
}

2 个答案:

答案 0 :(得分:3)

您可以通过SelectMany执行许多子选择:

var result = products
            .SelectMany(x => x.CategoryGroups)
            .GroupBy(x => x.CategoryGroupId)
            .Select(x => new CategoryGroup
                         {
                             Categories = x.SelectMany(y => y.Categories)
                                           .Distinct(y => y.CategoryId)
                                           .OrderBy(y => y.CategoryId)
                                           .ToList(),
                             CategoryGroupId = x.Key,
                             Name = x.Values.First().Name
                         })
            .OrderBy(x => x.CategoryGroupId)
            .ToList();

答案 1 :(得分:0)

以下是获取所有不同类别组的查询

   var categoryGroups = products.SelectMany(g => g.CategoryGroups)
                                     .GroupBy(x => x.CategoryGroupId)
                                     .Select(y => new { CategoryGroupId = y.Key,
                                                    Categories = y.SelectMany(category => category.Categories).Distinct().ToList()                                          });

要消除重复的类别,您必须修改Category对象以实现IEquatable接口,如下所示

 public class Category : IEquatable<Category>
{
    public int CategoryId { get; set; }
    public string Name { get; set; }

    public bool Equals(Category other)
    {
        //Check whether the compared object is null. 
        if (Object.ReferenceEquals(other, null)) return false;

        //Check whether the compared object references the same data. 
        if (Object.ReferenceEquals(this, other)) return true;

        //Check whether the products' properties are equal. 
        return CategoryId.Equals(other.CategoryId) && Name.Equals(other.Name);
    }

    // If Equals() returns true for a pair of objects  
    // then GetHashCode() must return the same value for these objects. 

    public override int GetHashCode()
    {

        //Get hash code for the Name field if it is not null. 
        int hashProductName = Name == null ? 0 : Name.GetHashCode();

        //Get hash code for the Code field. 
        int hashProductCode = CategoryId.GetHashCode();

        //Calculate the hash code for the product. 
        return hashProductName ^ hashProductCode;
    }
}

实现接口允许LINQ中的Distinct()调用比较对象列表并消除重复。

希望有所帮助。