DataMember for an EntityCollection

Posts   
 
    
Arif
User
Posts: 29
Joined: 01-Dec-2005
# Posted on: 23-Jan-2006 05:54:49   

Using Adapter scenario, build 1.0.2005.1 (Nov 30th 2005) with VS2005...

What can I set the DataMember property for an EntityCollection to? I am loading a graph of Orders & their related/prefetched Customer entities into a collection called orderColl & I dont understand how I can set this property & bind these 2 entites. I keep getting:

'Child list for field Orders cannot be created. '

I have tried setting the DataMember to Order,Orders,OrderEntity, etc...


orderColl = new EntityCollection(new OrderEntityFactory());
            IRelationPredicateBucket bucket = new RelationPredicateBucket();
            bucket.PredicateExpression.Add(
                                            (OrderFields.StartDate >= DateTime.Now.Subtract(new TimeSpan(90,0,0,0))) &
                                            (OrderFields.Assigned == 0)
                                          );
            IPrefetchPath2 prefectpath = new PrefetchPath2((int)EntityType.OrderEntity);
            prefectpath.Add(OrderEntity.PrefetchPathCustomer);
            
            DataAccessAdapter adapter = new DataAccessAdapter(true);
            try
            {
                adapter.FetchEntityCollection(orderColl, bucket, prefectpath); 
            }
            finally
            {
                adapter.CloseConnection(); 
            }

.....
<Example>

dataGridView1.DataSource = orderColl;
dataGridView1.DataMember = "Order";

dataGridView2.DataSource = orderColl;
dataGridView2.DataMember = "Customer";


Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 23-Jan-2006 14:59:34   

You don't need the DataMember for the first binding.

so just do the following:

dataGridView1.DataSource = orderColl;
dataGridView1.Databind(); // for ASP.NET

For the second binding:

dataGridView2.DataSource = orderColl;
dataGridView2.DataMember = "Customer"; // or "Customers" whatever the related collection is called.
dataGridView1.Databind(); // for ASP.NET
Arif
User
Posts: 29
Joined: 01-Dec-2005
# Posted on: 23-Jan-2006 16:45:01   

The second binding still doesnt work. The related entity is called CustomerEntity. I tried setting the DataMember to Customer, Customers, CustomerEntity, etc. Same error.

In an EntityCollection of OrderEntity objects are the related CustomerEntity objects (that are prefetched with the Order) bindable? All properties/fields of the OrderEntity can be set as DataMembers of the EntityCollection object in a simple databinding scenario (i.e. Textbox) but the collection of related CustomerEntity objects dont appear to be bindable.


dataGridView1.DataSource = orderColl;
dataGridView1.DataMember = "Customer";

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 23-Jan-2006 16:52:05   

Please take care that the EntityName may differ than the related entity name.

To know it for sure, either look it up in the LLBLGen Pro Designer or with the VS.NET intelli-sence as follows:

OrderEntity Order = new OrderEntity(); Order. ??? this will give you the member variables names including the related entities.

Sorry if this seems too trivial, but it's a common mistake.

Arif
User
Posts: 29
Joined: 01-Dec-2005
# Posted on: 23-Jan-2006 17:16:09   

Thanks for pointing that. The property to access the related entity is called 'Customer'. But the description for it from Intellisense states that:

"....This property is not visible in databound grids".

And I am still not able to bind to that.

bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 24-Jan-2006 04:40:16   

So are you trying to retrieve all orders that fit the criteria and then for all of these orders you want to show all of their customers in a different grid at once? If that is the case you may be better served by having two collections that you bind. I assume you are doing this on a web site since you are using the DataBind method. If you are doing the classic parent -> child grid relationship you may be better served by setting the datasource of the child when the parent's index has changed. This way you can only fill the second grid with the specific customers for that order and not have to fetch all of them.

Arif
User
Posts: 29
Joined: 01-Dec-2005
# Posted on: 24-Jan-2006 07:14:50   

Actually, I am doing this on a WinForm project and in this example using the new DataGridView control only to test this dual binding scenario. The DataBind() method was not from my code.

Yes, its definately NOT a classical parent child relation. Order-Customer is a "has-a" relationship.

What I would like to be able to do ideally is:

  1. Fetch my filtered list of OrderEntity objects in my orderColl EntityCollection. Assume this will be bound to datagrid1.

  2. Fetch all CustomerEntity objects that are associated with the OrderEntity objects I previously fetched. This list of customers would be bound to datagrid2 (i.e. this is not a master-detail scenario).

If I understand you correctly, I think you are saying that I would need to create 2 separate EntityCollection objects & make 2 DB calls to fill these collections? In that case, can you show me some example code of how I can fetch CustomerEntity collection applying the filter on an OrderEntity field (since I want customers for the set of filtered orders). I looked a bit into SubPath but that seems to only build a graph & i would think only the root entity of the graph would be bindable (current issue).

Right now, only to be able to move forward and bind to datagrid2 the related entities, I am using the code below. But its hardly efficient & I would never want to put this in on a production app.


            customerColl = new EntityCollection(new CustomerEntityFactory());
            foreach (OrderEntity oe in orderColl.Items)
            {
                CustomerEntity ce = oe.Customer;
                customerColl.Add(ce);
            }

Let me know what is the best way to fetch these 2 sets of entities for separate binding. tx.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39930
Joined: 17-Aug-2003
# Posted on: 24-Jan-2006 10:19:44   

You need 2 collections because order.Customer isn't a collection, so you can't set it to DataMember, as that expects it to be an IList implementing collection (and it's a single object).

First, define the filter for the orders.


IPredicateExpression filter = new PredicateExpression( (OrderFields.StartDate >= DateTime.Now.Subtract(new TimeSpan(90,0,0,0))) &
(OrderFields.Assigned == 0));

then fetch the orders in collection orders:


EntityCollection orderColl = new EntityCollection(new OrderEntityFactory());
adapter.FetchEntityCollection(orderColl, new RelationPredicateBucket(filter));

Now fetch all customers. We'll re-use the filter we just created and will create a query like: select * from customer where customerid in (select customerid from orders where <orderfilter>)

This is done using a FieldCompareSetPredicate. Fetch code for customer


RelationPredicateBucket filterCustomer = new RelationPredicateBucket();
filterCustomer.PredicateExpression.Add(new FieldCompareSetPredicate(
    CustomerFields.CustomerId, null,
    OrderFields.CustomerId, null,
    SetOperator.In,
    filter));
EntityCollection customers = new EntityCollection(new CustomerEntityFactory());
adapter.FetchEntityCollection(customers, filterCustomer);

Frans Bouma | Lead developer LLBLGen Pro