views:

455

answers:

2

Is it possible to convert:

public IList Get() { return Session.CreateCriteria(typeof(T)).List(); }

to return IQueryable?

What is the difference between IList and IQueryable?

+3  A: 

One of the most important aspects when thinking of SQL and Linq is that returning IList means that the query has been executed. Returning IQueryable keeps open the option of deferring the sql execution later (so you could potentially build on the query outside of this method).

However, this would only be the case with NHibernate when using the Linq to NHibernate provider. The Criteria API is not Linqified for the SQL statements. So realistically in this instance returning IList or IQueryable has no significant difference.

Michael Gattuso
+1  A: 

What is possible is to return an IEnumerable like this:

public IEnumerable<T> Get() 
{ 
    return Session.CreateCriteria(typeof(T)).Future<T>(); 
}

This way you can do deferred execution as you do with Linq to SQL.

For more info about the Future method see:

http://ayende.com/Blog/archive/2009/04/27/nhibernate-futures.aspx

You can also simulate the IQueryable by returning the ICriteria interface instead of an IList:

public ICriteria<T> Get() 
{ 
    return Session.CreateCriteria(typeof(T)); 
}

This way you can start building the query outside of your method and finally execute it whenever you want.

tolism7
Not entirely true. Future<T>() does defer the execution of the SQL for the purpose of combining many individual SQL calls into a MultiQuery (on supported databases). This is entirely different from Linq deferred execution. You could not, for example, appennd Linq statements outside of the method, a where statement for example, and have it affect the SQL that would be sent to the database. Using Future NHibernate would return the Criteria as expressed and then Linq to Objects would filter out the additional Where statement in memory.
Michael Gattuso
That said, you should always use Future with Criteria when possible, there is no reason not to use it. Just don't expect Linq to SQL functionality from it
Michael Gattuso
I will have to dissagree with you on that. The purpose of Future<T>() is not to combine queries only. For that purpose the CreateMultiQuery and the CreateMultiCriteria do a great job. If you read carefully Ayende's blog post he says: "...They essentially function as a way to defer query execution to a later date...." Future<T> is here to defer execution primarily and not to combine queries (secondary benefit). I have seen it work and tested it, and is not entirey different from Linq's deferred execution. It is very similar.
tolism7
tolism7
Just read Ayende's comments in the post you linked. Future is at heart a wrapper for MultiCriteria. The whole point is to defer loading to see if there are other database calls it can combine with in a MultiQuery. Note that Future fails over to standard db calls if MultiQuery is not supported on the database.
Michael Gattuso
I'll give you that ICriteria was there before Linq. Unfortunately the question was regarding IEnumerable and IQueryable (IQueryable being a Linq interface). had it been between IEnumerable and ICriteria we would have likely been on the same page. I'll give you that a method returning ICriteria and IQueryable have some similar functionality but a method that return the result of Future<T> is nothing like IQueryable. Once you call Future<T> you can no longer modify the SQL that will be sent only time it's sent.
Michael Gattuso
I cannot understand what are you arguing for. I merely stated in my answer that Future<T> can offer deferred execution and it does. Saying that because it does not allow changing the query dynamically does NOT justify it as ENTIRELY different thing as what Linq offers. I have even discribed that even some of the query changing capabilities are also availble for NHibernate bringing it even closer to what Linq offers. Even if Future<T> works towards query batching it does so by deferring execution and that is why I gave the answer above.
tolism7