Groups using anonymous type in Linq

Say I have an Employee class, and GetAllEmployees () returns a list of the employee instance. I want to group employees by department and gender, so I have an answer

var employeeGroup = Employee.GetAllEmployees() .GroupBy(x => new { x.Department, x.Gender }) // I don't understand this anonymous type .OrderBy(g => g.Key.Department) .ThenBy(g => g.Key.Gender) .Select(g => new { //I can understand this anonymous type Dept = g.Key.Department, Gender = g.Key.Gender, Employees = g.OrderBy(x => x.Name) }); 

I have two questions:

  • Why does an anonymous type allow a group with multiple keys?

  • I do not understand the first anonymous type, because, in my opinion, the format of the anonymous type should be like this

    new {field1 = x.Department, field2 = x.Gender}

Why can the first anonymous type be borderless? I mean, this is the correct syntax to write something like this:

 var anonymous = new {field1 = 1,field2 =2} 

But there will be a compilation error if I write it like this:

 var anonymous = new {1, 2} //compile error !!! 
+7
c # linq
source share
1 answer

Anonymous types can be used here to group across multiple fields, because GroupBy uses the default GroupBy .
By default, equality mapping for each anonymous type property is used for equality mapping for anonymous types.

So, for the first anonymous type, two instances are equal if both Department and both Gender are equal (according to their default equality mappers).

You can imagine that an anonymous type looks something like this:

 public class AnonymousType1 { public int Department { get; set; } // I don't know your department type public int Gender { get; set; } // neither your gender type public int GetHashCode() { return Department.GetHashCode() ^ Gender.GetHashCode(); } public bool Equals(AnonymousType1 other) { if (ReferenceEquals(other, null)) return false; return Department == other.Department && Gender == other.Gender; } } 

The second question is also simple: the compiler uses property names ( Department from x.Department and Gender from x.Gender ) as property names of an anonymous type.

So,

 var anon = new { employee.Department, employee.Gender } 

creates a type with the Department property and the Gender property.
Of course, this can only work with existing properties / names, and not with constant values ​​such as

 var anon = new {1,2}; // fails to compile, no names provided. 
+15
source share

All Articles