re-setting the entity collection after a predicate filter

Posts   
 
    
yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 05-Apr-2006 22:57:31   

version 1.0.2005.1 final (self-servicing) VS2005 winforms


hiya,

I am doing a simple predicate filter on an entity collection.


IPredicateExpression filter = new PredicateExpression();
filter.Add(PredicateFactory.CompareValue(TblDeliveryProductsFieldIndex.DeliveryId, ComparisonOperator.Equal, currDeliveryId));

 currDeliveries.GetMulti(filter);           

A simple question really, how can I RESET my entityCollection, so that it contains ALL the original entities?

eg, I filter by deliveryId = 16..it displays correctly

I then filter by deliveryId = 15, it seems that all the entities apart from deliveryId = 16 have been removed.

WHY isn't the entire entityCollection available again?Should I have to reset it?

Am I missing a point here?

many thanks,

yogi

bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 06-Apr-2006 02:43:35   

Hi Yogi,

I'm a little confused, what do you mean by

I then filter by deliveryId = 15, it seems that all the entities apart from deliveryId = 16 have been removed.

Can you show us the code that is executed for the second filter and the binding? What should happen is that the second time you run the listed code you only have entities that have deliveryIds of 15. It should run another query to fill the collection.

yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 06-Apr-2006 12:16:48   

hiya Brian,

It should run another query to fill the collection.

Ok, I think that is my issue, somehow, this quesry is not being run.

I don't have the code in front of me at the minute.

I use the SAME call for both filters, the filter value is passed as an arg

<pseudo>

private void filterBy( filterValue)

//set up the filter, based on the arg //apply the filter

myEntCollection.GetMulti( myFilter);

</pseudo>

I can confirm that the: 1) filterValue is always correct. 2) entityCollection and the underlying database do indeed contain correct values.

So, I take it that myEntCollection.GetMulti( myFilter); should:

1) search the entire entityColletion, 2) then filter

What I mean is: 1) if I filter by fliterValue = 16, then it should iterate thru the ENTIRE, unfiltered collection, selecting only the rows where the value is 16?

2) if I then SUBSEQUENTLY filter by fliterValue = 15, then it should iterate thru the ENTIRE, unfiltered collection, selecting only the rows where the value is 15?

I think that the first filter call correctly filters the rows...good so far

However, I think that 2nd second filter call returns nothing, because ( and I'm guessing here) the entityCollection only contains a SINGLE row, which of course has the value of the first filter call?

I want the 2nd filter call to filter the entire entCollection, NOT the (subset) entityCollection that was created as the result of the 1st filter.

I'll stop now, because I think I'm clouding the issue.Please also be aware that I am not "chaining" filters, or anything complicated...It's a single filter for the entire page.

many thanks,

yogi

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 06-Apr-2006 15:59:54   

It should filter the entire rows in the database table. Please post some real code so we can examine it. thanks

You may try to clear your entitycollection before the second filtering to remove the old entities.

yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 07-Apr-2006 00:49:35   

hiya,

The code I have is similar to the c# northwind example. I use the selected Id of a datagridView row in another winform to set the filter.



 IPredicateExpression filter = new PredicateExpression();  //declared at top of winform.
private void txtViewDeliveries_Click(object sender, EventArgs e)
        {
            frmDeliverySelection deliverySelector = new frmDeliverySelection();
            deliverySelector.ShowDialog(this);

            //a delivery is selected from the datagridView 
            SetDeliveryAsCurrent(deliverySelector.SelectedDeliveryId);  
         }

 private void SetDeliveryAsCurrent(int currDeliveryId)
        {
                       filter.Add(PredicateFactory.CompareValue(TblDeliveryProductsFieldIndex.DeliveryId, ComparisonOperator.Equal, currDeliveryId));
            
                       DisplayDeliveries(); 
        }

 private void DisplayDeliveries()
        {

            currDeliveries.Clear();  // I have tried to comment this out, it makes no difference.
            currDeliveries.GetMulti(filter);
currDeliveries.SupportsSorting = true;
            
            tblDeliveryProductsCollectionBindingSource.DataSource = currDeliveries;
            dgvDeliveryProducts.DataSource = tblDeliveryProductsCollectionBindingSource;
        }       

As I say, when I clear the entityColection it makes no difference. Does the code sample show where I am going wrong?

many thanks,

yogi

bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 07-Apr-2006 04:15:30   

Hey Yogi,

So you are certain that

private void txtViewDeliveries_Click(object sender, EventArgs e)
        {
            frmDeliverySelection deliverySelector = new frmDeliverySelection();
            deliverySelector.ShowDialog(this);

            //a delivery is selected from the datagridView 
            SetDeliveryAsCurrent(deliverySelector.SelectedDeliveryId); 
         }

is passing a different value for SelectedDeliveryId every time this is executed? I understand the scenario that you are think about with the collection, but that doesn't happen. When you call getmulti it executes another query. You do not need the Clear(). I have setup the same scenario on my computer using a combobox to select a department and then a grid which displays this departments employees. Here is the code for it. I realize this could be better, but I think it's simple enough to show the same behavior. Does any of this look different than what you are doing?

public Form1()
        {
            InitializeComponent();
            departmentCollection1.GetMulti(null);
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            ComboBox combo = (ComboBox)sender;
            EmployeeCollection employees = new EmployeeCollection();
            IPredicateExpression filter = new PredicateExpression();
            filter.Add(EmployeeFields.DepartmentId == (int)combo.SelectedValue);
            employees.GetMulti(filter);
            bindingSource1.DataSource = employees;
            dataGridView1.DataSource = bindingSource1;
        }
JimHugh
User
Posts: 191
Joined: 16-Nov-2005
# Posted on: 07-Apr-2006 06:48:24   

By not redeclaring the filter each time, you are adding additional AND predicate clauses to the predicate expression.

Based on your earlier examples The first time is DeliveryID = 15 the second time it is DeliveryID = 15 AND DeliveryID = 16 which should return nothing.

You need to reset the filter each time. Move the filter declaration inside of the SetDeliveryAsCurrent method and modify the DisplayDeliveries function to accept a filter.

On a side note, you should not need to reset the dgvDeliveryProducts datasource each time. Changing the datasource on the bindringsource is sufficient.


private void txtViewDeliveries_Click(object sender, EventArgs e)
        {
            frmDeliverySelection deliverySelector = new frmDeliverySelection();
            deliverySelector.ShowDialog(this);

            //a delivery is selected from the datagridView 
            SetDeliveryAsCurrent(deliverySelector.SelectedDeliveryId); 
         }

private void SetDeliveryAsCurrent(int currDeliveryId)
        {
                     IPredicateExpression filter = new PredicateExpression(); 
                     filter.Add(PredicateFactory.CompareValue(TblDeliveryProductsFieldIndex.DeliveryId, ComparisonOperator.Equal, currDeliveryId));
            
                     DisplayDeliveries(filter);
        }

private void DisplayDeliveries(IPredicateExpression filter)
        {
            currDeliveries.Clear();
            currDeliveries.GetMulti(filter);
            currDeliveries.SupportsSorting = true;
            
            tblDeliveryProductsCollectionBindingSource.DataSource = currDeliveries;
        }  

yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 07-Apr-2006 22:55:30   

spot on Jim,

Many thanks,

yogi

bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 08-Apr-2006 03:14:43   

Thanks Jim, I didn't pick up on it either flushed .