Master Detail with LLBLGenProDataSource2 and Prefetch for Detail

Posts   
 
    
neilx
User
Posts: 267
Joined: 02-Nov-2007
# Posted on: 20-Jun-2010 13:01:49   

v2.6 October 2009, Adapter, Win 7, Sql Server 2008

I am creating a master-details page with a nested ASPxGridView. It all works correctly with the master EntityCollection I create, but I am stuck on how to define that the details grid should use a Prefetch Path of that EntityCollection. Here is the code I am using: [code]

<llblgenpro:LLBLGenProDataSource2 ID="clients" runat="server" AdapterTypeName="MyCompany.BusinessObjects.Adapter.DatabaseSpecific.DataAccessAdapter, MyCompany.BusinessObjects.Adapter" DataContainerType="EntityCollection" EntityFactoryTypeName="MyCompany.BusinessObjects.Adapter.FactoryClasses.ClientEntityFactory, MyCompany.BusinessObjects.Adapter" LivePersistence="false" OnPerformSelect="Clients_PerformSelect"> </llblgenpro:LLBLGenProDataSource2> <dx:ASPxGridView ID="ASPxGridView1" runat="server" DataSourceID="clients" KeyFieldName="IDClient"> <SettingsDetail ShowDetailRow="True"></SettingsDetail> <Templates> <DetailRow> <dx:ASPxGridView ID="ASPxGridView2" runat="server" DataSourceID="clients" SettingsDetail-IsDetailGrid="True"> </dx:ASPxGridView> </DetailRow> </Templates> </dx:ASPxGridView> [code]

The code accessed via the Clients_PerformSelect event handler to create the EntityCollection is:


        public LLBLGenProDataSource2 LoadDataSource(LLBLGenProDataSource2 clients)
        {
                var client = (from a in metaData.Client
                               where a.ClientName.StartsWith("c")
                               select a).IncludeFields(a => a.ClientName)
                               .WithPath(b=>b.Prefetch(c=>c.DomainName));
                clients.EntityCollection =
                    ((ILLBLGenProQuery)client).Execute<EntityCollection<ClientEntity>>();
            return clients;
        }

This gives a master grid with details grid being exactly the same, just as expected from the above code.

So I want the details ASPxGridView to use the clients.DomainName prefetch path instead of clients but I can't work out how to do this, even after reading the examplesconfused

neilx
User
Posts: 267
Joined: 02-Nov-2007
# Posted on: 20-Jun-2010 19:18:23   

btw I just tried separating this into two distinct LLBLGenProDataSource2s with the master and details entity collections referenced independently,and linking them using a Session variable for the MasterRowKeyValue from the details grid. This works, but it seems odd that the PrefetchPath of my EntityCollection isn't used at all. If this is the right way to do this, it leaves me wondering why I am using an EntityCollection with all its prefetch power!

The details grid looks like this

            <dx:ASPxGridView ID="ASPxGridView2" runat="server" AutoGenerateColumns="True" 
                DataSourceID="domainnames" KeyFieldName="DomainNameID" 
                OnBeforePerformDataSelect="DomainName_BeforePerformDataSelect" 
                SettingsDetail-IsDetailGrid="True">
                <SettingsDetail IsDetailGrid="True" />
            </dx:ASPxGridView>

The new event is:


        protected void DomainName_BeforePerformDataSelect(object sender, EventArgs e)
        {
            HttpContext.Current.Session["IDCLient"] = ((ASPxGridView) sender).GetMasterRowKeyValue();
        }

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 20-Jun-2010 23:28:36   

As a workaround you can intercept OnPerformSelect on the Details LLBLGenProDataSource2 and set the underlying collection to the related prefetchted collection of the current item in master grid. Did you tried that already?

David Elizondo | LLBLGen Support Team
neilx
User
Posts: 267
Joined: 02-Nov-2007
# Posted on: 21-Jun-2010 10:13:37   

daelmo wrote:

As a workaround you can intercept OnPerformSelect on the Details LLBLGenProDataSource2 and set the underlying collection to the related prefetchted collection of the current item in master grid. Did you tried that already?

Yes. I just tried it, and that works too, but I don't think I gain anything over just using the EntityCollections as flat tables like my previous example.

I probably have a conceptual misunderstanding of what I think happens. I had imagined that:

  • the first time through, the master EntityCollection gets created without details (it does).
  • on expanding a master row, I had expected to be able to add the .WithPath for the details (filtered by the selected master row primary key)
  • the details grid, now visible, should be set with the PrefetchPathToUse
  • the fieldnames in the prefetched path would then be available to the grid.
  • no need to pass the master row key as it implicit in the Prefetch path being used.

In the current approaches I have tried, the objects to fill the master and details grids are completely independent. The details grid has no way to access the .WithPath of the master grid's EntityCollection. Setting the PrefetchPathToUse has no effect as far as I can tell.

Although I can move on with what works, I have 30 or 40 of these things to do in the next 6 months. Many of the master controls will have multiple details controls (one for each of the many to many relationships that exist for the master table). I wanted to make sure I am using the most effective approach before I start! All suggestions are welcome including rtfm:-)

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 21-Jun-2010 10:37:19   

First of all I have to question whether or not you want to use PrefetchPaths in Master Details ASP.NET GUI.

As prefetchPaths will fetch all related entities of all fetched main entities. Generally it will be enough to only fetch entities related to the Main Grid selected row. And only when a user select another row (if he ever does), you will need to fetch entities related to that row.

So in general you don't need a prefetchPath here, just a couple of LLBLGenProDataSources and a selectParameter in the details one, to build its filter on the PK selected from the first grid.

neilx
User
Posts: 267
Joined: 02-Nov-2007
# Posted on: 21-Jun-2010 11:43:12   

@Walaa - I guess that's the way I have managed to get it working.

Is the LLBLGenProDataSource2.PrefetchPathToUse property obsolete then? I think seeing this property in the Reference Manual (and in Intellisense) must have have led me to think I could do some magic with it.

If so, apart from being able to use an EntityCollection directly, what are the benefits of an LLBLGenProDataSource2 over using any of the other data sources that are available? Perhaps in an Eval or Bind I can pick things from the PrefetchPath, making its use in a single control possible.

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 21-Jun-2010 14:08:57   

Is the LLBLGenProDataSource2.PrefetchPathToUse property obsolete then?

No it's not, still it has its uses, say you are fetching Products, and instead of CategoryId, you want to display CategoryName from the related CategoryEntity, so you may use a PreftehcPath to fetch the CategoryEntity along with the ProductEntity, and display the CategoryName with the Product properties.

Perhaps in an Eval or Bind I can pick things from the PrefetchPath, making its use in a single control possible.

Exactly.

neilx
User
Posts: 267
Joined: 02-Nov-2007
# Posted on: 21-Jun-2010 15:08:15   

@Walaa - Super. I learn a little bit more every day:-)

My Master Detail grid with editing of the detail is now running. It all works fine and using the LLBLGenProDataSource2 object, it all seems to be very easy. Apart from handling some events, almost no code at all. Thanks to you both!