Combining Prefetch Paths

Posts   
 
    
dizlexik
User
Posts: 7
Joined: 27-Apr-2010
# Posted on: 17-Jan-2012 23:03:27   

Is there a way I can combine/chain prefetch paths with WithPath in the same sort of way I can with other Linq constructs like Where, etc? For example I might do something like:

var products = Products.Where(p => p.IsActive);
var blueProducts = products.Where(p => p.Colors.Any(c => c.Name == "Blue"))

So I'd like to do something similar with WithPath, like:

var products = Products.WithPath(p => p.Prefetch(pp => pp.Colors));
var listA = products.WithPath(p => p.Prefetch(pp => pp.Sizes));
var listB = products.WithPath(p => p.Prefetch(pp => pp.Shapes));

Hopefully this makes sense. It's kind of a lame contrived example but I have this similar need with a couple sets of search results that display different properties of a resultset but share some of them in common. I'd rather not have to duplicate these prefetch paths in both if possible but it seems like a new call to WithPath overwrites any previous ones. Thanks in advance!

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39908
Joined: 17-Aug-2003
# Posted on: 18-Jan-2012 11:41:05   
var listA = products.WithPath(p => p.Prefetch(pp => pp.Sizes));  // A
var listB = products.WithPath(p => p.Prefetch(pp => pp.Shapes)); // B

Statement A creates a new expression tree and statement B does too. .WithPath() isn't altering 'products', it is simply appending to it and returning that. So statement A and statement B are independent. So this means the withpath call in statement A isn't in the query of statement B.

Frans Bouma | Lead developer LLBLGen Pro
dizlexik
User
Posts: 7
Joined: 27-Apr-2010
# Posted on: 18-Jan-2012 15:48:38   

Right, they are definitely separate queries. My goal though was for A to prefetch both Colors and Sizes and B to prefetch both Colors and Shapes. However, neither of them will prefetch Colors because WithPath seems to overwrite prefetch paths instead of appending them with each successive call. I'm imagine this must be by design for some reason, although it would be great if it worked the other way. Is there a workaround that I could use for now to merge these somehow?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39908
Joined: 17-Aug-2003
# Posted on: 19-Jan-2012 11:32:41   

Multiple WithPath calls aren't supported (as they method is moved to the outside and it can be unclear what to merge with what if there are multiple calls), though you can either do one of the two things:

1) use the WithPath overload which uses PathEdge objects. Create a method to produce the pathedge instances for the particular fetch and pass them to WithPath.

or 2) use a method to produce the lambda (Expression<Func<>>) with multiple .Prefetch calls, which is then passed to the WithPath call.

So you're not augmenting an existing query with a prefetch but construct the particular prefetch when you're fetching the data. Don't know whether this is doable in your situation.

Frans Bouma | Lead developer LLBLGen Pro
dizlexik
User
Posts: 7
Joined: 27-Apr-2010
# Posted on: 19-Jan-2012 17:33:27   

Not really feasible for my situation, but thanks for breaking it down for me. I've resorted to manually duplicating the prefetch paths where needed for now and letting subsequent WithPath calls overwrite earlier ones. Not very elegant but a whole lot quicker than a major architecture overhaul simple_smile Thanks again for your help, it's very much appreciated!