按值对复杂类型进行分组

时间:2013-01-21 13:08:34

标签: c# linq

我有这个对象:

notes:[ 
     { user: {
           name: "A",
           group:{
                id:1,
                name:"Group 1"
           }
     }, 
     { user: {
           name: "B",
           group:{
                id:1,
                name:"Group 1"
           }
    }]

我需要按组进行分组..所以我尝试了这个:

foreach (IGrouping<Group, Note> item in notes.GroupBy(n => n.User.Group))
{
    var groupName = item.Key.Name;

    foreach (var note in item)
    {
        //
    }
}

但是我遇到了一个问题,因为分组不起作用(我认为这是因为它使用了对复杂类型进行分组的引用)。 如果我将n.User.Group更改为n.User.GroupId,则可以正常工作,但如果我这样做,则无法获取群组名称。

4 个答案:

答案 0 :(得分:3)

您需要在Group类中重写Equals和GetHashCode。 R#为它生成这种代码:

public class Group
{
    public int GroupId { get; set; }
    public string Name { get; set; }

    protected bool Equals(Group other)
    {
        return GroupId == other.GroupId;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((Group) obj);
    }

    public override int GetHashCode()
    {
        return GroupId;
    }
}

答案 1 :(得分:3)

是的,这是正确的。默认情况下,类都是唯一的,但您可以覆盖唯一性。

  1. 覆盖Equals(object obj)&amp;组对象上的GetHasCode()实现自己的平等
  2. 实施IEqualityComparer<Group>并将其作为GroupBy方法的第3个参数传递。

答案 2 :(得分:1)

你有几个选择:

  • 确保组对象的类实现GetHashCode和Equals。实现这些可以像比较组内的ID一样简单
  • 按ID分组,并将组名称grom作为分组中第一个用户的组。所有分组用户都属于同一个组,因此名称将相同
  • 如果您无法访问组类的源,请按实际GetHashCode和Equals的包装进行分组,并根据其包装的组的ID进行分组。

答案 3 :(得分:0)

您可以利用比较匿名类并写为

notes.GroupBy(n => new{n.User.Group.ID,n.User.Group.Name});