alex wrote:
Here is what I need to accomplish and maybe you could help me to find a more efficient way of doing this in LLBLGen:
I have an Animal entity that is associated with a Location entity. Each animal resides in a certain location. The Location is a hierarchical structure - each location may have a parent location (Site - Building - Floor – Room – Sub-room). The users should be able to filter animals not just by a specific location, but also by a branch, for ex. they want to get all animals located in all rooms and sub-rooms of the Floor1.
I was going to build the ID list of all locations that are sub-locations of the specified location and set this list in the predicate expression.
Ah, the classic hierarchy in one table problem
(the original is the all famous Employees table setup everybody remembers from the books which has a 'Supervisor' field pointing to self.
There are a couple of solutions.
One is the easiest to apply to your current setup. You have a fixed hierarchy and you can then use several subquery (fieldcompareset) predicates to retrieve the data. This is though very awful, as it will break the minute you add a layer to your hierarchy. Example:
SELECT * FROM Animal WHERE LocationID IN
(select LocationID from Location
WHERE Type='Floor' AND name ='Floor1')
OR
(select LocationID from Location
WHERE Type='Room' AND ParentID IN (SELECT LocationID FROM Location WHERE name Type='Floor' AND name='Floor1')
OR
etc...
This is very slow. Not recommended
Another solution is to use a 'precalc' table. This solution is what I use in our CMS which drives llblgen.com. That CMS has 'categories', to which you can add an item. To find all parents of a given category, I made a table which for each category contains all parents in the path to the root. This means that if I have a given category, I can fetch with 1 select all childs and childs of childs etc. and sort them by hierarchy as well.
The table is filled by a trigger, which updates the table when the categories table is modified (a row is modified/deleted/added)
This then could greatly enhance your performance as the query to fetch all animals from a given floor is very simple.
A 3rd way to do this is by using the Joe Celko method: click here
This 3rd way is the most performant and doesn't require a second precalc table, however it requires you to re-store the data in a different way, and inserting a row can be a bit slower than others.