Consider the following simplified objects and relationships:
public class Job{
int JobId;
String name;
String status;
Discipline disc;
WorkCategory workCat;
}
public class Discipline {
int DisciplineId;
String DisciplineName;
}
public class Workcategory{
int WorkCategoryId;
String WorkCategoryName;
}
public Class Grouping{
Discipline parent;
List<Workcategory> children;
}
The above models a relationship that a Job is associated with one Discipline and one WorkCategory. The Workcategory is always a child of a specific parent Discipline (one-to-many relationship). We can assume that the relationship of the assigned Discipline and Workcategory will always be valid.
The issue I am facing is when I am trying to create a Grouping result object based on filters that are applied to Jobs. I am not sure If this can be done or if the approach I am taking is even correct. The exact question itself is not clear to me, however the above defines the problem statement.
- Can the design be improved?
- How can I group Jobs by Discipline and Workcategory?
- Do I even need the
Groupingclass?
I have tried the following (this is my first attempt using Linq), but to no success as my understanding is not complete enough. The other alternative is to first get the Discipline group and loop through the original grouping picking up the related Workcategory.
var grouping = repository.GetJobsWithActiveStatus()
.GroupBy(x => new {
x.Discipline.DisciplineID,
x.Discipline.DisciplineName,
x.Category.WorkCategoryID,
x.Category.WorkCategoryName
})
.Select(g => new Grouping{
Discipline = new Discipline{
DisciplineID = g.Key.DisciplineID,
Name = g.Key.DisciplineName
},
Categories = ?? // this is where I am lost
}});
Edit:
After having posted this, I realized that the inital GroupBy parameters result in one group of item whereas I am looking for Group-SubGroup result.
Edit 2:
To clarify a bit further, I dont want the associated Jobs as part of the result, but rather the Discipline-Workcategory grouping – thus the reason for the Grouping class
Initial solution based on @Obalix
Edit 7-Mar-2010:
This solution does not work – The GroupBy on the object Discipline will yield a unique grouping for each object. I think this is due to it being a reference type. Am I correct?
I initially accepted this as the answer, however after some head scratching realised that my mock data itself was faulty. The initial questions still remain answered.
var result = repository.GetJobsWithActiveStatus()
.GroupBy(x => x.disc)
.Select(g => new Grouping
{
Discipline = g.Key,
Catergories = g.GroupBy(x=>x.workCat) // <--- The Problem is here, grouping on a reference type
.Select(l=>l.Key) // needed to select the Key's only
.ToList()
});
Here is a description how you can implement an hierarchical grouping mechanism.
A generic way of doing this using LINQ (as shown in the link) is:
However, the link also describes an alternative way which allows you to do the following:
Edit: Following Ahmad’s comment here is the strongly typed version: