LINQ to LLBLGen, PostFetch

Posts   
 
    
TazMizZaz
User
Posts: 37
Joined: 29-Apr-2009
# Posted on: 22-Jan-2010 20:44:44   

I'm using LINQ and building out a very nice and useful Business Layer. What has been pestering me lately is how to PostFetch entities.

When I know beforehand that I will be using certain sub entities it makes sense to use prefetch paths and all that. Sometimes though one part of the application will make the fetch and in a different area I need certain information that is located in a sub object. While I could of course just perform a standard query I cannot seem to get that data to "hook" back into the main object.

I'm using the Adapter pattern.

An example:

I have a work order entity, there are multiple children entities like costs and laborers. Normally I don't need to know the data in the children but when I do I would like to be able to fill in the WorkOrderEntity.Labor field with the labor collection, etc. Prefetch this is easy, I haven't been able to figure out how to do this after the original fetch has occurred though.

Thanks.

rdhatch
User
Posts: 198
Joined: 03-Nov-2007
# Posted on: 22-Jan-2010 21:33:21   

Hi Taz -

You have two options when expanding the graph, as I see it:

1.) Refetch using the PrefetchPaths. This will automatically populate LaborCollection, etc. according to your Prefetch Paths.

If you have changes on your WorkOrderEntity, you can preserve them by using the Context object.

Pseudo code:

Context context = new Context();
context.Add(workOrder);
adapter.FetchEntity(workOrder, prefetchPaths, context);

When you expand the Graph using Prefetches - You always need to refetch the Root entity. Realize - You can also expand the Graph from a different node, without refetching all entities in the graph. For instance, if you had: WorkOrder.Customer in your graph and you needed WorkOrder.Customer.Addresses - you would only need to Prefetch on the Customer... you would not need to Refetch the WorkOrder. Make sense?

2.) Manual Fetch & Populate. Ugly. You would need to populate the related entities by hand. Fetch a LaborCollection using a PredicateExpression that matches the primary key for your WorkOrderEntity. You will then need to move all the LaborEntities over to the workOrder using workOrder.Labor.AddRange(...). The only thing you save using this method is the WorkOrder isn't refetched & there are no Context ObjectID lookups. But this is a pain.

If I were you - I would either prefetch immediately, or prefetch when you need the expanded graph.

Hope this helps -

Ryan

TazMizZaz
User
Posts: 37
Joined: 29-Apr-2009
# Posted on: 22-Jan-2010 21:47:55   

Just to get a little clarity on what you are proposing.

1)

I normally fetch everything using LINQ so I would use code like:

var q = from c in MetaData.WorkOrder
            where c.pk == 1
            select c;

Then I would add prefetches with:

q = q.Prefetch(p=>p.Labor);

So how would I build prefetches for this option you are talking about or is there a LINQy way of doing it?

2) I tried doing it the ugly way except the problem is wo.Labor == null so I cannot do anything with that object as well as it is readonly just to make my life more fun and interesting.

I plan on building this whole thing into my DL or BL so ugly and excessive code isn't really a problem as long as its fairly efficient and of course, works.

rdhatch
User
Posts: 198
Joined: 03-Nov-2007
# Posted on: 22-Jan-2010 22:33:38   

Yes, that's correct - You just need to set the Context first, so the reference to your existing Work Order is maintained. The Context will extend the existing Graph instead of giving you a new one.

Pseudo code:


// Create Context with existing Work Order
Context context = new Context();
context.Add(workOrder);

// Create MetaData & Set Context
LinqMetaData meta = New LinqMetaData();
meta.Context = context;

// Build Linq Query to Refetch Work Order
var q = from c in meta.WorkOrder
            where c.pk == workOrder.pk
            select c;

// Assign Prefeches to Linq Query
q = q.Prefetch(p=>p.Labor);

See here: http://www.llblgen.com/documentation/2.6/Using%20the%20generated%20code/Linq/gencode_linq_generalusage.htm#UsingContext

Hope this helps!

Ryan

PS. I don't view the LLBLGen adapter methods as ugly. wink

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 23-Jan-2010 01:05:59   

In addition to what Ryan said: If you want to build your query, add prefetches in other methods, and execute it LATER in other part of your code, you can do that. See Setting variables on the Linq Provider.

David Elizondo | LLBLGen Support Team
TazMizZaz
User
Posts: 37
Joined: 29-Apr-2009
# Posted on: 23-Jan-2010 21:11:08   

Thanks. I think that fixes it for me. Now just to figure out and write the code...