There is an organisation with several departments and each department has a few employees.
I have created the following object model:
public class O
You need to do all three levels of sorting inside the objects that you return, like this (I'll show only the "Retail", the "Institutional" needs to be sorted in the same way):
{
"Retail", organisations
.Where(x => x.Type == "Retail")
.OrderBy(x => x.Code).ThenBy(x => x.Name)
.Select(x => new Organisation {
x.Code
, x.Type
, x.Name
, Departments = x.Departmentsd.OrderBy(d => d.Code).ThenBy(d => d.Name)
.Select(d => new Department {
d.Code
, d.Name
, Employees = d.Employees.OrderBy(e => e.Code).ThenBy(e => e.Name).ToList()
})
}).ToList()
}
Since you need to select this multiple times, you may want to wrap this code in a method, and use it from several spots, like this:
private Organisation SortedOrganisation(Organisation x) {
return new Organisation {
x.Code
, x.Type
, x.Name
, Departments = x.Departmentsd.OrderBy(d => d.Code).ThenBy(d => d.Name)
.Select(d => new Department {
d.Code
, d.Name
, Employees = d.Employees.OrderBy(e => e.Code).ThenBy(e => e.Name).ToList()
})
};
}
...
var legalEntitiesCollectionByType = new Dictionary<string, ICollection<Organisation>>
{
{
"Institutional", organisations
.Where(x => x.Type == "Institutional")
.OrderBy(x => x.Code).ThenBy(x => x.Name)
.Select(SortedOrganisation)
.ToList()
},
{
"Retail", organisations
.Where(x => x.Type == "Retail")
.OrderBy(x => x.Code).ThenBy(x => x.Name)
.Select(SortedOrganisation)
.ToList()
}
};
var legalEntitiesCollectionByType = new Dictionary<string, ICollection<Organisation>>
{
{
"Institutional", organisations
.Where(x => x.Type == "Institutional")
.ToList()
.Select(o => new Organisation{Code = x.Code,Departaments = x.Departaments.OrderBy(c => c).ToList() }).ToList()
}
}
If Employees ever need to be sorted by code and name then you can make that property a SortedList<>.
public class Department
{
...
public SortedList<Tuple<int, string>, Employee> Employees { get; set; }
}
Prior to .NET 4 you could use KeyValuePair instead of Tuple.
When creating Employees object you'd need to provide IComparer object for sorted list's key.
Employees = new SortedList<Tuple<int, string>, Employee>(new EmployeeKeyComparer());
where EmployeeKeyComparer could be defined as
public class EmployeeKeyComparer : IComparer<Tuple<int, string>>
{
public int Compare(Tuple<int, string> x, Tuple<int, string> y)
{
if (x.First == y.First)
return StringComparer.Ordinal.Compare(x.Second, y.Second);
else
return x.First.CompareTo(y.First);
}
}
I know this is an old question, but there's a simpler way of achieving the same result:
organisations = organisations.OrderBy(org =>
{
org.Departments = org.Departments
.OrderBy(dept =>
{
dept.Employees = dept.Employees
.OrderBy(employee => employee.Code)
.ThenBy(employee=>employee.Name);
return dept.Code;
})
.ThenBy(dept=>dept.Name);
return org.Code;
})
.ThenBy(org=>org.Name);
You can sort before :
organisations.ToList().ForEach(o => o.Departments = o.Departments.OrderBy(d => d.Code).ToList());
organisations.SelectMany(o => o.Departments).ToList().ForEach(d => d.Employees = d.Employees.OrderBy(e => e.Name).ToList());
And then use the list already sorted
var legalEntitiesCollectionByType = new Dictionary<string, ICollection<Organisation>>
{
{
"Institutional", organisations
.Where(x => x.Type == "Institutional")
.ToList()
},
{
"Retail", organisations
.Where(x => x.Type == "Retail")
.ToList()
}
};
NB : the sort is not in place, you can achieve this using a comparer
organisations.ToList().ForEach(o => o.Departments.Sort(CreateCustomComparison));
organisations.SelectMany(o => o.Departments).ToList().ForEach(d => d.Employees.Sort(CreateCustomComparison));