Best way to retrieve entities: Looping? Filters? Linq?

Posts   
 
    
JuanV
User
Posts: 12
Joined: 08-Jul-2007
# Posted on: 18-Jan-2008 23:45:26   

What are the performance and other implications of the different methods of retrieving entities?

I've looked around the forums for this answer, perhaps if it's been addressed someone can send me a link. I'm just wondering what method of selecting entities is best performance wise (and any other reasons anyone can think of). Some benchmarks or just numbers for comparison would be nice.

Are any of the approaches more suited to large or small datasets?

I've included three examples for selecting the orders that have shipped before now from a customer:

ShipDateCustomerEntity Customer = new CustomerEntity(id);
OrderCollection orders = customer.Orders;

Looping:

foreach (OrderEntity order in Customer.Order)
{
    if (order.ShipDate < DateTime.Now)
    {
        orders.Add(order);
    }
}

LLBLGen Filters:

CustomerEntity customer = new CustomerEntity(id);
OrderCollection orders = customer.Orders;

IPredicateExpression main_filter = new PredicateExpression();
main_filter.Add((OrderFields.ShipDate <= DateTime.Now));
orders.GetMulti(main_filter);

LINQ: I know this is upcoming in 2.6, but perhaps the devs can comment on this.

OrderCollection orders = customer.Orders;
var query = 
    from o in Orders
    where c.ShipDate <= DateTime.Now
    select c;

Thanks for an excellent product and brilliant support!

Posts: 254
Joined: 16-Nov-2006
# Posted on: 19-Jan-2008 23:13:41   

Well in the way you've written the "LLBLGen Filters" scenario, the looping code would actually be quicker. However you can actually get the filter scenario to perform better than the looping scenario if you modify it slightly.

The issue with this code

OrderCollection orders = customer.Orders;

IPredicateExpression main_filter = new PredicateExpression();
main_filter.Add((OrderFields.ShipDate <= DateTime.Now));
orders.GetMulti(main_filter);

Is all related Orders from a customer would be retrieved and then again a collection would be built up by applying the predicate main_filter. Instead you could simply retrieve all orders associated with the customer and apply a predicate together i.e.

IPredicateExpression main_filter = new PredicateExpression();
main_filter.Add((OrderFields.ShipDate <= DateTime.Now));
customer.GetMultiOrders(true, main_filter);
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 20-Jan-2008 14:18:01   

Add to Matt's post: predicate usage in-memory as well as Linq to Objects simply mean: loop over the IEnumerable/collection and apply the predicate onto each element. If an element matches: use it, otherwise skip it.

So there's no speed gain when using either one of them over your own loops simple_smile

Frans Bouma | Lead developer LLBLGen Pro
JuanV
User
Posts: 12
Joined: 08-Jul-2007
# Posted on: 24-Jan-2008 17:48:04   

Otis wrote:

Add to Matt's post: predicate usage in-memory as well as Linq to Objects simply mean: loop over the IEnumerable/collection and apply the predicate onto each element. If an element matches: use it, otherwise skip it.

So there's no speed gain when using either one of them over your own loops simple_smile

Thanks so much. I would guess the way then to optimize would be to use prefetch paths before the loading all customer orders?

JV