tags:

views:

76

answers:

3

This is a pretty simple question. When I do this:

session.CreateCriteria(typeof(Product)).List();

The resulting list will load as I access it? Let's say, from 100 to 100 elements for example? Or will it load all once?

In the case it's not "virtual" how can I make it so? What's the best pratice about it?

Thanks;

+2  A: 

When you call the List() method the query will be executed (and load all at once). If it would load the entities as you access them it would cause some potential "Select N+1" queries that could slow your application down a lot and you might not notice it before it's live.

I would say that in most cases you do want the query to be executed when you call the List() method and instead specify the rows you want in the query. You could, however, use linq to nhibernate and work with the IQueryable interface to limit the result set at a later stage.

Bottom line is that it might sound like a very good idea to load the entities as you access them. But in many cases it will cause some heavy problems (like Select N+1 queries) that can kill your application.

A very good tool to profile nhibernate is nhprof. If you haven't checked it out already I would really recommend it.

Mattias Jakobsson
+1  A: 

NHibernate has a feature called Futures which will delay the execution of the query for later. For instance:

class MyDao
  public IEnumerable<Product> GetProducts()
    return session.CreateCriteria(typeof(Product)).Future<Product>;


var list = MyDao.GetProducts(); // this has not be executed yet
... // some other code here
// query has not been executed yet

foreach (var o in list) // this will cause the query to be executed via IEnumerable
  Console.WriteLine(o.Name);
kibbled_bits
Kibbled, thanks for your response. I didn't know about Future. Will Future load all at once or it's on demand ? (e.g loading 100 records per time as I iterate it)
Ciwee
A future will simply delay the execution. It will not Batch selects. If you want batch retrieval, there is a batch-size attribute on the class level (in your HBM file). I haven't used batch at that level before.If batching is something you are looking for, you could enable batching in your DAO itself. The pattern for this would be similar to doing custom pagination with NHibernate.
kibbled_bits
+1  A: 

With List all at once With Future all at once with only one round-trip batched with other queries where you have used Future. With Enumerable all at once but will instantiates the entities during iteration.

Fabio Maulo
Thanks for your response Fabio. Can you please explain a little better the phrase "at once with only one round-trip batched with other queries where you have used Future"? Thanks in advance.
Ciwee