Ok I have several tables linked together.
Departments (k = departmentID)
Functions (k = functionID, fk = departmentID)
Processes (k = processID, fk = functionID)
Procedures (k = procedureID, fk = processID)
So they all have their relationships setup when trying to come up with some linq I run into some oddities.
The below code will return me
Departments.Select(s => s.Functions)
But when trying to expand that query further it will not let me. I'd like to be able to join all of the above tables and pull information out of them as I need it.
Departments.Select(s => s.Functions.Process.Procedure) // Errors out
Further more I can do the following:
Functions.Select(s => s.Processes)
It seems it will do it for two tables but no more than 2? Am I missing something?
Here's the thing. The Departments
to Functions
relationship is one to many. So when you just write,
Departments
you have a collection of Department
objects. Since each Department
object has its own collection of Function
objects, doing:
Departments.Select(departmentObject => departmentObject.Functions)
gives you a collection of collections of Function
objects.
If you want to aggregate all these together, you have to use a different method, specifically
Departments.SelectMany(departmentObject => departmentObject.Functions)
which says "get the collection of collections of Function
objects and make them into one big collection of Function
objects"
What you are trying to do is:
Departments.Select(departmentObject => departmentObject .Functions.Process.Procedure)
But, this can't possibly work, because you are asking a collection of Function
objects for its Process
property. But, a collection of Function
objects doesn't have a Process
property. A Function
object, itself, has a Process
property. So, what you are really trying to do is:
Departments
.SelectMany(departmentObject => departmentObject.Functions)
.Select(functionObject => functionObject.Process.Procedure)
which basically translates to "get the collection of collections of Function
objects and make them into one big collection of Function
objects. Then, get the Procedure
property of the Process
property of each Function
object".
So, what you should be expecting here is just a collection of the procedures that are performed by the processes of any function associated with any of the departments.
Note, that if there is any overlap in the Functions of Departments, in the Processes of Functions, or in the Procedures of Processes, then you may get some duplicate Procedures in your end result. If this isn't what you want, then you can use the Distinct()
method to remove duplicates, and you should do so at any point where there is overlap, but there should not be duplication. You can get the same result by simply adding Distinct()
to the end of the query, but you will have better performance if you kill the duplicates along the way. So, in reality, your query will probably look like something in between the following and previous query, depending on how much overlap there is and how much duplication you want:
Departments
.SelectMany(departmentObject => departmentObject.Functions)
.Distinct()
.Select(functionObject => functionObject.Process)
.Distinct()
.Select(processObject => processObject.Procedure)
.Distinct();