binding to a repeater, with joined tables

Posts   
 
    
Bexm
User
Posts: 8
Joined: 23-May-2007
# Posted on: 19-Jun-2007 16:58:33   

Hello

I have two tables, products and portalproduct. These tables are linked by productID. The portal products table has an order column. In my repeater I want to show the productname and other product details from the product table and order from the portalproduct table.

Below is how I create my entity collection


     EntityCollection products = new EntityCollection(new ProductEntityFactory());

            RelationPredicateBucket bucket = new RelationPredicateBucket();

            SortExpression sorter = new SortExpression(PortalProductFields.Order | SortOperator.Ascending);
            IPredicateExpression filter = new PredicateExpression();
            filter.Add(PortalProductFields.PortalId == PortalID);

        
            IEntityRelation relation = new EntityRelation();
            relation.AddEntityFieldPair(ProductFields.Id, PortalProductFields.ProductId);

            bucket.PredicateExpression.Add(filter);
            bucket.Relations.Add(relation);

            using (DataAccessAdapter adapter = new DataAccessAdapter()) {
                adapter.FetchEntityCollection(products, bucket, 0, sorter);
            }


and here is my repeater:



asp:Repeater runat="server" ID="rptProducts">
    <ItemTemplate>
        <div class="descblock">
        </div>
            <table width="100%" cellspacing="5">
                <tr>
                    <td style="width:150px" align="center">
                        <asp:ImageButton CausesValidation="false" runat="server" ID="imgProductImg" 
                        ImageUrl='<%# String.Format("~/Images/Products/{0}", DataBinder.Eval ( Container.DataItem, "Image")) %>' OnCommand="Proceed" CommandArgument='<%# DataBinder.Eval ( Container.DataItem, "ID") %>'/>                     
                    </td>
                    <td>
                        <span class="title"><strong><%# DataBinder.Eval ( Container.DataItem, "Name") %></strong></span><br /><br />                    
                        <%# DataBinder.Eval ( Container.DataItem, "Description") %>
                    </td>
                    <td style="width:100px" align="center" >
                                                                            
                        <asp:ImageButton  CausesValidation="false" runat="server"
                            ID="imgMoveUp" OnCommand="Move" ImageUrl="~/images/ArrowU.gif" CommandArgument='<%# DataBinder.Eval ( Container.DataItem, "ID")  + "," +  DataBinder.Eval ( Container.DataItem, "PortalProduct.Order") %>'
                             /><br />
                            
                                        
                    </td>
                </tr>
            </table>
    </ItemTemplate>
</asp:Repeater>



I know I am obviously doing something wrong as I get the following error, but I can't work our what:

DataBinding: 'HelperClasses.EntityCollection`1[[EntityClasses.PortalProductEntity, EntityLayer, Version=0.0.1.0, Culture=neutral, PublicKeyToken=5a6e058bae69689a]]' does not contain a property with the name 'Order'.

Please help, or point me in the direction of an example that shows me how to do this...

Thanks

Bex

Aurelien avatar
Aurelien
Support Team
Posts: 162
Joined: 28-Jun-2006
# Posted on: 19-Jun-2007 17:21:22   

Hi,

First, I don't see a prefetchpath from products to portalproduct so PortalProduct would be set to nothing.

Also, I'm not sure complex binding like "PortalProduct.Order" is allowed in Eval method. Can anyone confirm ?

Bexm
User
Posts: 8
Joined: 23-May-2007
# Posted on: 19-Jun-2007 17:24:51   

Hello!

Thanks for that! Yes I have just realised I am missing the prefetch path.. I am quite new to llbl and am finding it quite complicated to get round, so keep missing bits.

As for the binding, I would also like to know if this is possible. If not, whats a way round?

Bex

Bexm
User
Posts: 8
Joined: 23-May-2007
# Posted on: 19-Jun-2007 17:38:20   

Hello!

I now have this creating my entity collection, but am still receiving the same error..

Any ideas? Is the code below right?

 EntityCollection products = new EntityCollection(new ProductEntityFactory());

            IRelationPredicateBucket bucket = new RelationPredicateBucket();
        
            //SortExpression sorter = new SortExpression(PortalProductFields.Order | SortOperator.Ascending);

            PredicateExpression filter = new PredicateExpression();
            filter.Add(PortalProductFields.PortalId == PortalID);

            bucket.Relations.Add(ProductEntity.Relations.PortalProductEntityUsingProductId);
            bucket.PredicateExpression.Add(filter);


            IPrefetchPath2 prefetchPath = new PrefetchPath2((int)EntityType.ProductEntity);
            prefetchPath.Add(ProductEntity.PrefetchPathPortalProduct);
    
            using(DataAccessAdapter adapter = new DataAccessAdapter()) {
                adapter.FetchEntityCollection(products, bucket, prefetchPath);
            }
Bexm
User
Posts: 8
Joined: 23-May-2007
# Posted on: 19-Jun-2007 18:33:05   

Hello

Ok I have done some testing on this...

This code brings back an entity collection and has values under document and order.. I mean when I add a watch in visual studio and dig down, if I put orderItems[0] I get the field names and values next to the prefetch items, I can also call document.Filename in the databinder.Eval.

EntityCollection orderItems = new EntityCollection(new OrderDetailEntityFactory());

            IRelationPredicateBucket bucket = new RelationPredicateBucket();

            PredicateExpression filter = new PredicateExpression();
            filter.Add(OrderFields.OrderId == orderID);

            bucket.Relations.Add(OrderDetailEntity.Relations.OrderEntityUsingOrderId);
            bucket.Relations.Add(OrderDetailEntity.Relations.DocumentEntityUsingDocumentId);
            bucket.PredicateExpression.Add(filter);


            IPrefetchPath2 prefetchPath = new PrefetchPath2((int)EntityType.OrderDetailEntity);
            prefetchPath.Add(OrderDetailEntity.PrefetchPathOrder);
            prefetchPath.Add(OrderDetailEntity.PrefetchPathDocument);

            using(DataAccessAdapter adapter = new DataAccessAdapter()) {
                adapter.FetchEntityCollection(orderItems, bucket, prefetchPath);
            }
            return orderItems;

This, on the otherhand is identical as far as I can see, but the portalproduct in the watch view when expanded only shows "base", and has no values or column names for any of the columns in this table.. (here's the code)

            EntityCollection products = new EntityCollection(new ProductEntityFactory());

            IRelationPredicateBucket bucket = new RelationPredicateBucket();
        
            //SortExpression sorter = new SortExpression(PortalProductFields.Order | SortOperator.Ascending);

            PredicateExpression filter = new PredicateExpression();
            filter.Add(PortalProductFields.PortalId == PortalID);

            //bucket.Relations.Add(ProductEntity.Relations.PortalProductEntityUsingProductId);
            bucket.PredicateExpression.Add(filter);

            IPrefetchPath2 prefetchPath = new PrefetchPath2((int)EntityType.ProductEntity);
            prefetchPath.Add(ProductEntity.PrefetchPathPortalProduct);
    
            using(DataAccessAdapter adapter = new DataAccessAdapter()) {
                adapter.FetchEntityCollection(products, bucket, prefetchPath);
            }

I cannot understand why one works and not the other, please can someone shed some light? This is driving me nuts..!

Walaa avatar
Walaa
Support Team
Posts: 14952
Joined: 21-Aug-2005
# Posted on: 20-Jun-2007 18:15:29   

I cannot understand why one works and not the other, please can someone shed some light? This is driving me nuts..!

These are not the same. As the OrderDetails contains one object/entity for the Document and one object/entity for the Order as it appears to me.

But the Product contains a collection of PortalProducts, right?