PrefetchPath bug

Posts   
 
    
Nevidion
User
Posts: 17
Joined: 28-Nov-2010
# Posted on: 20-May-2011 12:22:40   

Using LLBLGen 3.1 (April 14th, 2011), Sql Server, Adapter .NET 3.5.

I'm having trouble with the following situation, i have a many to many relationship between two entities (Item, Order), the table for the relationship is OrderHasItem. While fetching Items I'm trying the get orders for an item with all the items on those orders as well, so it's kind of a circural prefetch path.

eg. pfpItem.Add(ItemEntity.PrefetchPathOrderHasItem). SubPath.Add(OrderHasItemEntity.PrefetchPathOrder). SubPath.Add(OrderEntity.PrefetchPathOrderHasItems). SubPath.Add(OrderHasItemEntity.PrefetchPathItem);

The problem: In this situation my Orders have an extra OrderHasItem entity that is related to the original Item.

eg. One order with two Items in the database, starting from Item1 using the PrefetchPath from above gives: -Item1 has one OrderHasItem entity that ofc has an Order on in, the Order has 3 OrderHasItem entities!!

I'm attaching a simple repro solution thats a small console app and DB scripts, run the two sql scripts and run the console app to reproduce the problem.

I'm sure this in not so by design and my current workaround is to remove the extra OrderHasItem entity from the Order, but when working with a lot of data this is slowing things down.

Attachments
Filename File size Added on Approval
MTMRepro.llblgenproj 12,797 20-May-2011 12:23.13 Approved
Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 20-May-2011 15:08:29   

Are you fetching the entire items and orders, or are there any kind of filtering? I'm asking this coz I believe you have to restructure how you fetch the graph. E.g. You can fetch the orderHasItem table with prefetchPaths to Items and Orders.

Nevidion
User
Posts: 17
Joined: 28-Nov-2010
# Posted on: 20-May-2011 15:15:32   

Walaa wrote:

Are you fetching the entire items and orders, or are there any kind of filtering? I'm asking this coz I believe you have to restructure how you fetch the graph. E.g. You can fetch the orderHasItem table with prefetchPaths to Items and Orders.

The thing is that the EntityCollection<ItemEntity> I am fetching gets bound to a grid later, the grid allows filtering, sorting and all sorts of things so I'm kind of stuck at ItemEntity as my starting point for the fetch.

Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 20-May-2011 15:30:12   

This can be handled, as you can collect all Items in one collection.

But Anyway, another solution is to only fetch Items using one DataSource. And for the related Orders, leave that for another dataSource, which get a filter by the selected/expanded value of the Items Grid. (SelectParameters can be handy here).

This is far better than fetching the entire graph at one shot. Better to delay the fetch of Orers per user request.

Nevidion
User
Posts: 17
Joined: 28-Nov-2010
# Posted on: 20-May-2011 16:27:28   

Walaa wrote:

This can be handled, as you can collect all Items in one collection.

As I mentioned I found a workaround for the problem, but I still see it as a bug, am I wrong?

Walaa wrote:

But Anyway, another solution is to only fetch Items using one DataSource. And for the related Orders, leave that for another dataSource, which get a filter by the selected/expanded value of the Items Grid. (SelectParameters can be handy here).

This is far better than fetching the entire graph at one shot. Better to delay the fetch of Orers per user request.

Well, design discussions aside I'm not going to do that, the graph has to come in one shot for me, thanks for the effort anyway simple_smile

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 20-May-2011 23:14:37   

Nevidion wrote:

eg. pfpItem.Add(ItemEntity.PrefetchPathOrderHasItem). SubPath.Add(OrderHasItemEntity.PrefetchPathOrder). SubPath.Add(OrderEntity.PrefetchPathOrderHasItems). SubPath.Add(OrderHasItemEntity.PrefetchPathItem);

The problem: In this situation my Orders have an extra OrderHasItem entity that is related to the original Item.

I see. I wrote about this, please take a look at this post: http://www.llblgening.com/archive/2009/10/prefetchpaths-in-depth ... and go to "Common mistakes", then find "The X-Y-X Graph". It explains what is going on and how get it working wink

David Elizondo | LLBLGen Support Team
Nevidion
User
Posts: 17
Joined: 28-Nov-2010
# Posted on: 23-May-2011 09:31:09   

daelmo wrote:

Nevidion wrote:

eg. pfpItem.Add(ItemEntity.PrefetchPathOrderHasItem). SubPath.Add(OrderHasItemEntity.PrefetchPathOrder). SubPath.Add(OrderEntity.PrefetchPathOrderHasItems). SubPath.Add(OrderHasItemEntity.PrefetchPathItem);

The problem: In this situation my Orders have an extra OrderHasItem entity that is related to the original Item.

I see. I wrote about this, please take a look at this post: http://www.llblgening.com/archive/2009/10/prefetchpaths-in-depth ... and go to "Common mistakes", then find "The X-Y-X Graph". It explains what is going on and how get it working wink

Thanks a lot daelmo, like the blog and the article, just a question that might be very stupid but it's not obvious to me, why doesn't FetchEntityCollection support semantical context?

Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 23-May-2011 10:27:51   

You have to supply the Context explicitly, coz the framework deal with each prefetchPath alone.

Normally an entity collection has a property called DoNotPerformAddIfPresent

When set to true, an entity passed to Add() or Insert() will be tested if it's already present. If so, the index is returned and the object is not added again. If set to false this check is not performed.

This property is true by default.

During a multi-entity fetch, DataAccessAdapter's sets this property to false . Because if true it can slow down fetch logic. Since the for every entity fetched and to be inserted into this collection, the collection would be checked for a duplicate.

So by default in a multi-entity fetch, it is left for the developer to use a Context to avoid duplicates only in a Cyclic scenario.