Prefetch and DataBinding

Posts   
 
    
scott2187
User
Posts: 5
Joined: 03-Jul-2008
# Posted on: 03-Jul-2008 02:03:55   

Hello,

We're demoing llbl for a new project. I have been playing with LLBLGenPro 2.5/VS 2008/Adapter model for the last week or so and have a few questions in regards databinding on a web form.

I've seen how people are manually using the PerformSelect() method on a LLBLDataSource, but I want to expand on that a little bit.

Currently, I have a Facade to my LLBLGen stuff, which uses the prefetch Path pattern. This facade has a method called GetCustomerAndOrders(int CustomerPK) which returns a CustomerEntity with a populated collection Property(of type EntityCollection<orderEntity>) called orders. Note: in the future, I will expand on this method to return more than just an orders collection..maybe order details, etc.


CustomerEntity cust = GetCustomerAndOrders(10); //cust.Orders will be a populated graph



My question is, how would you, the pros, go about binding to the CustomerEntity and its corresponding Orders property while using my the GetCustomerAndOrders method? Would you use multiple LLBL DataSource controls? Would you bind at one and only event handler? Something like this?:


 protected void llblDSCustomers_PerformSelect(object sender, SD.LLBLGen.Pro.ORMSupportClasses.PerformSelectEventArgs2 e)
    {
        llblDSCustomers.EntityCollection = PermitMaintenance.GetCustomers(10);
    }

I've seen some threads on this forum about binding at design time, which I know we can't do, but I don't see any examples of my scenario.

Also, I know the syntax for prefetching is: da.FetchEntity(customer, prefetchPath); Lets say we already have a fully instantiated customer entity and do not require a DB lookup for the customer(root), but we do require a DB lookup for all of the prefetched paths - is it possible to bypass a DB lookup for the customer?

This is a long post, I know, and will gladly expand if needed. Thanks a lot!!

Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 03-Jul-2008 08:27:08   

My question is, how would you, the pros, go about binding to the CustomerEntity and its corresponding Orders property while using my the GetCustomerAndOrders method? Would you use multiple LLBL DataSource controls? Would you bind at one and only event handler?

,

It depends, if you want 2-way databinding all the way, then use multiple LLBLGenProDataSources, otherwise you might just bind to any collection if you need 2-way data binding.

In your case: using the Datasources, you'll need to handle the PerformSelect as you have done to bind to each available prefetched collection.

Also, I know the syntax for prefetching is: da.FetchEntity(customer, prefetchPath); Lets say we already have a fully instantiated customer entity and do not require a DB lookup for the customer(root), but we do require a DB lookup for all of the prefetched paths - is it possible to bypass a DB lookup for the customer?

Yes it is possible.

EntityCollection orders = customer.Orders;
adapter.FetchEntityCollection(orders, customer.GetRelationInfoOrders());
scott2187
User
Posts: 5
Joined: 03-Jul-2008
# Posted on: 03-Jul-2008 14:19:00   

otherwise you might just bind to any collection if you need 2-way data binding.

Do you mean 1-way binding?

Also

Also, I know the syntax for prefetching is: da.FetchEntity(customer, prefetchPath); Lets say we already have a fully instantiated customer entity and do not require a DB lookup for the customer(root), but we do require a DB lookup for all of the prefetched paths - is it possible to bypass a DB lookup for the customer?

Yes it is possible.

EntityCollection orders = customer.Orders;
adapter.FetchEntityCollection(orders, customer.GetRelationInfoOrders());

In the event that Customer has many collection properties (ex: Orders,Referrals, AppliedDiscounts,etc), could we stick to using the prefetch syntax and still avoid making a DB lookup for customer?

It seems like calling GetRelationInfoOrders() for each property could be a performance hit.

Anyway, I really appreciate the input. Thanks for the help and great product.

Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 03-Jul-2008 15:23:30   

otherwise you might just bind to any collection if you need 2-way data binding.

Do you mean 1-way binding?

Sorry yes I ment: otherwise you might just bind to any collection if you don't need 2-way data binding.

In the event that Customer has many collection properties (ex: Orders,Referrals, AppliedDiscounts,etc), could we stick to using the prefetch syntax and still avoid making a DB lookup for customer?

No you can't.

It seems like calling GetRelationInfoOrders() for each property could be a performance hit.

I doubt it. GetRelationInfoOrders, just create the appropriate filter. I don't think it can affect performance at any way.

scott2187
User
Posts: 5
Joined: 03-Jul-2008
# Posted on: 03-Jul-2008 21:30:06   

It seems like calling GetRelationInfoOrders() for each property could be a performance hit.

I doubt it. GetRelationInfoOrders, just create the appropriate filter. I don't think it can affect performance at any way.

The invocation of GetRelationInfo*() is probably not a performance hit, but I think what I'm trying to say is that the following could be a performance hit:

EntityCollection<orders> = customer.Orders; adapter.FetchEntityCollection(orders, customer.GetRelationInfoOrders());

AND

EntityCollection<Referrals> = customer.Referrals; adapter.FetchEntityCollection(Referrals, customer.GetRelationInfoOrders());

AND

EntityCollection<AppliedDiscounts> = customer.AppliedDiscounts; adapter.FetchEntityCollection(AppliedDiscounts, customer.GetRelationInfoOrders());

Doing a prefetch only requires connecting to the DB once, whereas each FetchEntitiyCollection() is a DB hit. Thanks.

Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 04-Jul-2008 11:25:13   

Doing a prefetch only requires connecting to the DB once, whereas each FetchEntitiyCollection() is a DB hit. Thanks

Not true, they are pretty much the same.

PrefetchPathing queries the database once for each related object type too.

What you can do to improve the performance is to keep the connection open for the adapter, and close it when you finish all your database calls.

DataAccessAdapter adapter = new DataAccessAdapter(true);
...
// do your calls
...
adapter.CloseConnection();
scott2187
User
Posts: 5
Joined: 03-Jul-2008
# Posted on: 05-Jul-2008 18:46:48   

Perfect. Thanks a lot.

scott2187
User
Posts: 5
Joined: 03-Jul-2008
# Posted on: 07-Jul-2008 18:54:44   

Walaa wrote:

Doing a prefetch only requires connecting to the DB once, whereas each FetchEntitiyCollection() is a DB hit. Thanks

Not true, they are pretty much the same.

PrefetchPathing queries the database once for each related object type too.

What you can do to improve the performance is to keep the connection open for the adapter, and close it when you finish all your database calls.

DataAccessAdapter adapter = new DataAccessAdapter(true);
...
// do your calls
...
adapter.CloseConnection();

Sorry to keep bumping this but I was doing some SQL Server Profiling. It looks like using the prefetch method only requires one connection. What I mean by this is that all of my queries were executed before 'sp_resectConnection' was executed.

When I used the adapter.FetchEntityCollection method, 'sp_resetConnection' was executed after each FetchEntityCollection invocation.

So it looks like the prefetch method is a little bit more efficient. If I am missing something, please let me know. Thanks

Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 08-Jul-2008 10:36:50   

When I used the adapter.FetchEntityCollection method, 'sp_resetConnection' was executed after each FetchEntityCollection invocation.

Please post your code of using multiple FetchEntityCollection().

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39870
Joined: 17-Aug-2003
# Posted on: 10-Jul-2008 14:40:14   

sp_resetConnection is called by the SqlClient code, not our code. It's a call made to make sure the connection is actually reset so it can be added to the connection pool. I.o.w.: the call is required and made by the sqlserver client's SqlConnection object when the connection is closed and the object is disposed.

Frans Bouma | Lead developer LLBLGen Pro