Selective polymorphic prefetching

Posts   
 
    
cebus2000
User
Posts: 29
Joined: 11-Jan-2006
# Posted on: 19-May-2008 16:38:55   

Hi folks. Want to see if anyone knows a solution to a problem we're having.

Part of our object model consists of a 'root' table named 'Usage.' it is generated as an Abstract class. There are ~40 Entities that derive from this base class (referred to as 'Usage Leaf' entities.) Usages are part of a larger entity, called a 'RoofAssembly,' and a RoofAssembly entity has 1-N Usages, of any of the available subtypes.

If we set up a regular Prefetch, the polymorphic prefetch feature works as expected- it will pick up all of the Usage Leaf subtypes correctly. Our problem is, there are a lot of Leaf tables to check, and some of the tables have tens of millions of rows. We end up with very long-running queries.

In the past, we worked around this by specifying an EntityFactory for the Prefetch path- this would result in only a single Leaf table being queried, in a sort of load-on-demand strategy. However, due to a change in requirements cry , we now need to load up the entire hierarchy at once.

What I was looking for was a way to pass a list of IEntityFactory2's to the Prefetch. Along the lines of "Do a polymorphic prefetch, but I only want to get these 5 Leaf types back, and ignore all other types that derive from Usage." I tried adding 'duplicate' Prefetch elements, each using a different Factory, but that threw an exception.

So... Anyone have suggestions on how to do this?

Thanks much.

cebus2000
User
Posts: 29
Joined: 11-Jan-2006
# Posted on: 19-May-2008 17:23:55   

One further note- if I use Entity Type filtering in my prefetch paths, I also get the desired result, as far as the Entities I end up with. However, the prefetch still generates the mega-query which LEFT JOINs all of my 40something leaf entity tables. That is what I want to avoid.

Thanks.

goose avatar
goose
User
Posts: 392
Joined: 06-Aug-2007
# Posted on: 19-May-2008 21:02:55   

Sorry if I missed your point, but, if you know the tables involved in advance (runtime I mean) you could just create the prefetch path for this involved tables using reflection.

cebus2000
User
Posts: 29
Joined: 11-Jan-2006
# Posted on: 19-May-2008 22:10:08   

goose wrote:

Sorry if I missed your point, but, if you know the tables involved in advance (runtime I mean) you could just create the prefetch path for this involved tables using reflection.

No, b/c of the way the inheritance relationships get generated (Adapter template). There are no prefetch paths created specifically for the 'leaf' subtypes. There are prefetch paths to the base entity (Usage) only. Which makes sense, else it would be rather hard to load up everything using the normal behavior.

If that abstract Usage entity was not marked to be generated as Abstract, then we would have the additional prefetch paths for all those relations, and we could use reflection, etc. Unfortunately, that would cause additional problems, that entity needs to remain an abstract.

The DQE is smart enough to know that any data in the 'base' table has corresponding data in the 'subtypes' tables, and it prefetches it by querying all possible subtype tables. What i need to do is give it some additional help, so it only looks in the subtype tables appropriate for a given scenario, instead of searching every table. Right now, I can do this for a single subtype, by passing an IEntityFactory2 to Subpath.Add(). I need to find a way to handle this for multiple subtypes.

Does that make it clearer?

Thanks!

Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 20-May-2008 10:34:43   

Since anyway, a query would be needed for each table.

You may: Fetch each subtype (using the entityFactory) using a single fetch call for each. (Please check the manual for: Generated code -> Adapter/SelfService -> Using the entity collection classes -> Entity retrieval into an entity collection object -> Using a related entity)

cebus2000
User
Posts: 29
Joined: 11-Jan-2006
# Posted on: 20-May-2008 14:47:22   

So, basically fetch and build up that part of the hierarchy myself? OK, I guess that answers my question about doing this via Prefetch.
Thanks again!