Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to order a collection and its subcollection using LINQ?

I have a collection of Employees, and each employee has a collection of Responsibilities. I would like to output a list of the employees sorted by Name and output their Responsibilities, sorted by Title.

So, it should be outputted like this:


Jane Jones

Responsibilities:

Responsibility A

Responsibility B

Mike Smith

Responsibilities:

Responsibility A

Responsibility C


To get the initial collection I use:

var employees = _context.Employees.OrderBy(e => e.Name);

but I can't seem to figure out how to order the Responsibilities subcollection as well.

I'm using MVC and my View receives a strongly typed Employee collection so I don't want to build and return an anonymous type.

like image 429
Matt Penner Avatar asked Dec 15 '10 22:12

Matt Penner


2 Answers

You could do something like:

var employees = _context.Employees.OrderBy(e => e.Name);
employees.ToList().ForEach(e => e.Responsibilities = e.Responsibilities.OrderBy(r => r.Name));
like image 153
devdigital Avatar answered Oct 16 '22 02:10

devdigital


1st approach: (is only suitable for LINQ to Objects with Responsibilities defined as IList)

You could copy into a new collection of Employees but this means that you need to re-copy each field into new employee, something like this:

var employees = from e in _context.Employees
                orderby e.Name
                select new Employee
                {
                    Name = e.Name,
                    ...re-assign other properties...
                    Responsibilities = e.Responsibilities.OrderBy(r => r.Name).ToList()
                };

2nd approach:

Using the DataLoadOptions. Basically, you create a DataLoadOptions object which specifies how to order a particular relationship, so in your case:

var options = new DataLoadOptions();
options.AssociateWith<Employees>(e => e.Responsibilities.OrderBy(r => r.Name));
_context.LoadOptions = options;

var employees = _context.Employees.OrderBy(e => e.Name);

The Responsibilities will be ordered automatically.

like image 34
Denis Ivin Avatar answered Oct 16 '22 02:10

Denis Ivin