Retrieve a collection filtering with another collection

Posts   
 
    
kal
User
Posts: 18
Joined: 25-May-2010
# Posted on: 31-May-2010 18:44:11   

Hi all,

In my code, I have a collection from a table T1 : T1Collection. This table contains a reference to another table T2.

I want to build a collection from T2 table where all entries are referenced from T1Collection. Best way I found to do this is something like :

foreach (T1Entity in T1Collection) T2Collection.Add ( new T2Entity(T1Entity.T2_ID));

Do you know better way for doing this ?

Regards, Kal

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 01-Jun-2010 05:10:31   

Doing your way you might have duplicates in T2Collection. Do you already fetch T1Collection? If T1 is Order and T2 is Customer, say you need a collection of Customers that already have some order(s), right? If that is the case, you can do something like:

[code]IPredicateExpression filter = new PredicateExpression();
filter.Add(new FieldCompareSetPredicate(
    CustomerFields.CustomerID, OrderFields.CustomerID,
    SetOperator.In, null));

CustomerCollection customers = new CustomerCollection();
customers.GetMulti(filter);
David Elizondo | LLBLGen Support Team
kal
User
Posts: 18
Joined: 25-May-2010
# Posted on: 01-Jun-2010 09:27:23   

daelmo wrote:

Doing your way you might have duplicates in T2Collection. Do you already fetch T1Collection? If T1 is Order and T2 is Customer, say you need a collection of Customers that already have some order(s), right? If that is the case, you can do something like:

[code]IPredicateExpression filter = new PredicateExpression();
filter.Add(new FieldCompareSetPredicate(
    CustomerFields.CustomerID, OrderFields.CustomerID,
    SetOperator.In, null));

CustomerCollection customers = new CustomerCollection();
customers.GetMulti(filter);

Indeed, I may have duplicates in T2Collection. It's not so easy, because my T1Collection results from a complex filtering (adding entries manually after checking criterias). So, using your way, I can't really pick T2 entries from those referenced in T1Collection. disappointed

By the way, I'm using LLBLGen Pro 2.0 with .NET 2.0. And yes, my T1Collection is already fetched! Thanks for your support wink

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 01-Jun-2010 09:33:45   

You have 2 options.

1- Collect the T2 IDs in an array, and then hit the database to fetch all T2 entities where the ID is in the specified range.

2- Refetch the T1 collection but this time using a prefetchPath to T2, then you can loop on T1 collection and collect the T2 entities in their own collection, and while having the DoNotPerformAddIfExist property of the T2 collection set to true, you will end up with no duplicates.

kal
User
Posts: 18
Joined: 25-May-2010
# Posted on: 01-Jun-2010 09:38:38   

Walaa wrote:

You have 2 options.

1- Collect the T2 IDs in an array, and then hit the database to fetch all T2 entities where the ID is in the specified range.

2- Refetch the T1 collection but this time using a prefetchPath to T2, then you can loop on T1 collection and collect the T2 entities in their own collection, and while having the DoNotPerformAddIfExist property of the T2 collection set to true, you will end up with no duplicates.

Thanks a lot for your answer! I have one question for each option : - For option 1, how do you specifie all IDs. I would do a filter and add each ID with AddWithOr(). Is that what you were thinking about? - For option 2, this is about the same code example I've posted above, in my first post? I never used prefetchPath, so I think I will go for option 1.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 01-Jun-2010 09:44:09   
  • Using FieldCompareRangePredicate

e.g.

int[] values = new int[3] {1, 2, 5};
filter.Add(new FieldCompareRangePredicate(
    OrderFields.EmployeeId, null, values));

// which is equal to:
filter.Add(OrderFields.EmployeeId == values);
  • The second option is not like the code in your first post. Your code will hit the database once for each T2 entity to fetch it.

While a prefetchPath will hit the database once to fetch all T2 entities.

kal
User
Posts: 18
Joined: 25-May-2010
# Posted on: 01-Jun-2010 10:07:29   

Walaa wrote:

  • Using FieldCompareRangePredicate

e.g.

int[] values = new int[3] {1, 2, 5};
filter.Add(new FieldCompareRangePredicate(
    OrderFields.EmployeeId, null, values));

// which is equal to:
filter.Add(OrderFields.EmployeeId == values);
  • The second option is not like the code in your first post. Your code will hit the database once for each T2 entity to fetch it.

While a prefetchPath will hit the database once to fetch all T2 entities.

It sounds very interesting, I want to give it a try. Currently, my code looks like :


            _clausesOffre = new CLAUSE_OFFRECollection();
            IPredicateExpression filterClauses = new PredicateExpression(CLAUSE_OFFREFields.Offre == _offre.ID);
            IPrefetchPath prefetchPath = new PrefetchPath((int)EntityType.CLAUSE_OFFREEntity);
            prefetchPath.Add(CLAUSE_OFFREEntity.PrefetchPathCLAUSE_).SubPath.Add(CLAUSEEntity.PrefetchPathGROUPE_CLAUSE);
            _clausesOffre.GetMulti(filterClauses, prefetchPath);

The point is that the documentation (here : http://www.llblgen.com/documentation/2.6/Using%20the%20generated%20code/SelfServicing/gencode_prefetchpaths.htm) doesn't seem to explain how browser the PrefetchPathElement object disappointed Do you have an example somewhere ?

Thanks!

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 01-Jun-2010 10:10:58   

You don't browse the prefetchPath objects, prefetchPaths fetches the entities and set them to their corresponding related entities properties of the main entities.

i.o.w. you should loop on T1 entities and check t1.T2.

kal
User
Posts: 18
Joined: 25-May-2010
# Posted on: 01-Jun-2010 10:18:51   

Walaa wrote:

You don't browse the prefetchPath objects, prefetchPaths fetches the entities and set them to their corresponding related entities properties of the main entities.

i.o.w. you should loop on T1 entities and check t1.T2.

Thanks Walaa, it works like a charm simple_smile