<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://nhforge.org/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results matching tag 'Future'</title><link>http://nhforge.org/search/SearchResults.aspx?o=DateDescending&amp;tag=Future&amp;orTags=0</link><description>Search results matching tag 'Future'</description><dc:language>en-US</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>NHibernate Futures</title><link>http://nhforge.org/blogs/nhibernate/archive/2009/04/27/nhibernate-futures.aspx</link><pubDate>Mon, 27 Apr 2009 05:33:00 GMT</pubDate><guid isPermaLink="false">45f813f2-f1c4-4eda-a619-288e3cadc793:260</guid><dc:creator>Ayende</dc:creator><description>&lt;p&gt;One of the nicest new features in NHibernate 2.1 is the Future&amp;lt;T&amp;gt;() and FutureValue&amp;lt;T&amp;gt;() functions. They essentially function as a way to defer query execution to a later date, at which point NHibernate will have more information about what the application is supposed to do, and optimize for it accordingly. This build on an existing feature of NHibernate, Multi Queries, but does so in a way that is easy to use and almost seamless.&lt;/p&gt;  &lt;p&gt;Let us take a look at the following piece of code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (var s = sf.OpenSession())
&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (var tx = s.BeginTransaction())
{
	var blogs = s.CreateCriteria&amp;lt;Blog&amp;gt;()
		.SetMaxResults(30)
		.List&amp;lt;Blog&amp;gt;();
	var countOfBlogs = s.CreateCriteria&amp;lt;Blog&amp;gt;()
		.SetProjection(Projections.Count(Projections.Id()))
		.UniqueResult&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;();

	Console.WriteLine(&amp;quot;&lt;span style="color:#8b0000;"&gt;Number of blogs: {0}&lt;/span&gt;&amp;quot;, countOfBlogs);
	&lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (var blog &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; blogs)
	{
		Console.WriteLine(blog.Title);
	}

	tx.Commit();
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;This code would generate two queries to the database:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_404AC599.png"&gt;&lt;img title="image" style="border-right:0px;border-top:0px;display:inline;border-left:0px;border-bottom:0px;" height="99" alt="image" src="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_thumb_5F00_4E41B6E9.png" width="798" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_12187BF2.png"&gt;&lt;img title="image" style="border-right:0px;border-top:0px;display:inline;border-left:0px;border-bottom:0px;" height="132" alt="image" src="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_thumb_5F00_7193CCF0.png" width="415" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_70BDF7B7.png"&gt;&lt;img title="image" style="border-right:0px;border-top:0px;display:inline;border-left:0px;border-bottom:0px;" height="77" alt="image" src="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_thumb_5F00_49863F33.png" width="292" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Two queries to the database is a expensive, we can see that it took us 114ms to get the data from the database. We can do better than that, let us tell NHibernate that it is free to do the optimization in any way that it likes, I have marked the changes in red:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (var s = sf.OpenSession())
&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (var tx = s.BeginTransaction())
{
	var blogs = s.CreateCriteria&amp;lt;Blog&amp;gt;()
		.SetMaxResults(30)
		&lt;strong&gt;&lt;font color="#ff0000"&gt;.Future&amp;lt;Blog&amp;gt;();&lt;/font&gt;&lt;/strong&gt;
	var countOfBlogs = s.CreateCriteria&amp;lt;Blog&amp;gt;()
		.SetProjection(Projections.Count(Projections.Id()))
		&lt;strong&gt;&lt;font color="#ff0000"&gt;.FutureValue&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;();&lt;/font&gt;&lt;/strong&gt;

	Console.WriteLine(&amp;quot;&lt;span style="color:#8b0000;"&gt;Number of blogs: {0}&lt;/span&gt;&amp;quot;, countOfBlogs&lt;strong&gt;&lt;font color="#ff0000"&gt;.Value&lt;/font&gt;&lt;/strong&gt;);
	&lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (var blog &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; blogs)
	{
		Console.WriteLine(blog.Title);
	}

	tx.Commit();
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, we seem a different result:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_38A19B43.png"&gt;&lt;img title="image" style="border-right:0px;border-top:0px;display:inline;border-left:0px;border-bottom:0px;" height="96" alt="image" src="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_thumb_5F00_5E99DC4A.png" width="795" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_453469C1.png"&gt;&lt;img title="image" style="border-right:0px;border-top:0px;display:inline;border-left:0px;border-bottom:0px;" height="163" alt="image" src="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_thumb_5F00_445E9488.png" width="394" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Instead of going to the database twice, we only go &lt;em&gt;once&lt;/em&gt;, with both queries at once. The speed difference is quite dramatic, 80 ms instead of 114 ms, so we saved about 30% of the total data access time and a total of 34 ms.&lt;/p&gt;

&lt;p&gt;To make things even more interesting, it gets better the more queries that you use. Let us take the following scenario. We want to show the front page of a blogging site, which should have:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A grid that allow us to page through the blogs.&lt;/li&gt;

  &lt;li&gt;Most recent posts.&lt;/li&gt;

  &lt;li&gt;All categories&lt;/li&gt;

  &lt;li&gt;All tags&lt;/li&gt;

  &lt;li&gt;Total number of comments&lt;/li&gt;

  &lt;li&gt;Total number of posts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For right now, we will ignore caching, and just look at the queries that we need to handle. I think that you can agree that this is not an unreasonable amount of data items to want to show on the main page. For that matter, just look at &lt;em&gt;this&lt;/em&gt; page, and you can probably see as much data items or more.&lt;/p&gt;

&lt;p&gt;Here is the code using the Future options:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (var s = sf.OpenSession())
&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (var tx = s.BeginTransaction())
{
	var blogs = s.CreateCriteria&amp;lt;Blog&amp;gt;()
		.SetMaxResults(30)
		.Future&amp;lt;Blog&amp;gt;();

	var posts = s.CreateCriteria&amp;lt;Post&amp;gt;()
		.AddOrder(Order.Desc(&amp;quot;&lt;span style="color:#8b0000;"&gt;PostedAt&lt;/span&gt;&amp;quot;))
		.SetMaxResults(10)
		.Future&amp;lt;Post&amp;gt;();

	var tags = s.CreateCriteria&amp;lt;Tag&amp;gt;()
		.AddOrder(Order.Asc(&amp;quot;&lt;span style="color:#8b0000;"&gt;Name&lt;/span&gt;&amp;quot;))
		.Future&amp;lt;Tag&amp;gt;();

	var countOfPosts = s.CreateCriteria&amp;lt;Post&amp;gt;()
		.SetProjection(Projections.Count(Projections.Id()))
		.FutureValue&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;();

	var countOfBlogs = s.CreateCriteria&amp;lt;Blog&amp;gt;()
		.SetProjection(Projections.Count(Projections.Id()))
		.FutureValue&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;();

	var countOfComments = s.CreateCriteria&amp;lt;Comment&amp;gt;()
		.SetProjection(Projections.Count(Projections.Id()))
		.FutureValue&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;();

	Console.WriteLine(&amp;quot;&lt;span style="color:#8b0000;"&gt;Number of blogs: {0}&lt;/span&gt;&amp;quot;, countOfBlogs.Value);

	Console.WriteLine(&amp;quot;&lt;span style="color:#8b0000;"&gt;Listing of blogs&lt;/span&gt;&amp;quot;);
	&lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (var blog &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; blogs)
	{
		Console.WriteLine(blog.Title);
	}

	Console.WriteLine(&amp;quot;&lt;span style="color:#8b0000;"&gt;Number of posts: {0}&lt;/span&gt;&amp;quot;, countOfPosts.Value);
	Console.WriteLine(&amp;quot;&lt;span style="color:#8b0000;"&gt;Number of comments: {0}&lt;/span&gt;&amp;quot;, countOfComments.Value);
	Console.WriteLine(&amp;quot;&lt;span style="color:#8b0000;"&gt;Recent posts&lt;/span&gt;&amp;quot;);
	&lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (var post &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; posts)
	{
		Console.WriteLine(post.Title);
	}

	Console.WriteLine(&amp;quot;&lt;span style="color:#8b0000;"&gt;All tags&lt;/span&gt;&amp;quot;);
	&lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (var tag &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; tags)
	{
		Console.WriteLine(tag.Name);
	}

	tx.Commit();
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;This generates the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_03BED8CA.png"&gt;&lt;img title="image" style="border-right:0px;border-top:0px;display:inline;border-left:0px;border-bottom:0px;" height="132" alt="image" src="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_thumb_5F00_05258C4D.png" width="789" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;And the actual SQL that is sent to the database is:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;&lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SELECT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;SELECT&lt;/a&gt; &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=top&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;top&lt;/a&gt; 30 this_.Id             &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;as&lt;/a&gt; Id5_0_,
              this_.Title          &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;as&lt;/a&gt; Title5_0_,
              this_.Subtitle       &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;as&lt;/a&gt; Subtitle5_0_,
              this_.AllowsComments &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;as&lt;/a&gt; AllowsCo4_5_0_,
              this_.CreatedAt      &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;as&lt;/a&gt; CreatedAt5_0_
&lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=FROM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;FROM&lt;/a&gt;   Blogs this_
&lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SELECT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;SELECT&lt;/a&gt;   &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=top&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;top&lt;/a&gt; 10 this_.Id       &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;as&lt;/a&gt; Id7_0_,
                this_.Title    &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;as&lt;/a&gt; Title7_0_,
                this_.&lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=Text&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;Text&lt;/a&gt;     &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;as&lt;/a&gt; &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=Text&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;Text&lt;/a&gt;7_0_,
                this_.PostedAt &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;as&lt;/a&gt; PostedAt7_0_,
                this_.BlogId   &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;as&lt;/a&gt; BlogId7_0_,
                this_.UserId   &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;as&lt;/a&gt; UserId7_0_
&lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=FROM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;FROM&lt;/a&gt;     Posts this_
&lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=ORDER&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;ORDER&lt;/a&gt; &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=BY&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;BY&lt;/a&gt; this_.PostedAt &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=desc&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;desc&lt;/a&gt;
&lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SELECT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;SELECT&lt;/a&gt;   this_.Id       &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;as&lt;/a&gt; Id4_0_,
         this_.Name     &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;as&lt;/a&gt; Name4_0_,
         this_.ItemId   &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;as&lt;/a&gt; ItemId4_0_,
         this_.ItemType &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;as&lt;/a&gt; ItemType4_0_
&lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=FROM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;FROM&lt;/a&gt;     Tags this_
&lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=ORDER&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;ORDER&lt;/a&gt; &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=BY&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;BY&lt;/a&gt; this_.Name &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=asc&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;asc&lt;/a&gt;
&lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SELECT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;SELECT&lt;/a&gt; &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=count&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;count&lt;/a&gt;(this_.Id) &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;as&lt;/a&gt; y0_
&lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=FROM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;FROM&lt;/a&gt;   Posts this_
&lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SELECT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;SELECT&lt;/a&gt; &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=count&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;count&lt;/a&gt;(this_.Id) &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;as&lt;/a&gt; y0_
&lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=FROM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;FROM&lt;/a&gt;   Blogs this_
&lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SELECT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;SELECT&lt;/a&gt; &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=count&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;count&lt;/a&gt;(this_.Id) &lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;as&lt;/a&gt; y0_
&lt;a style="color:#0000ff;" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=FROM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99"&gt;FROM&lt;/a&gt;   Comments this_&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is great, but what would happen if we would use List and UniqueResult instead of Future and FutureValue?&lt;/p&gt;

&lt;p&gt;I’ll not show the code, since I think it is pretty obvious how it will look like, but this is the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_61F8219A.png"&gt;&lt;img title="image" style="border-right:0px;border-top:0px;display:inline;border-left:0px;border-bottom:0px;" height="180" alt="image" src="http://nhforge.org/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/nhibernate/image_5F00_thumb_5F00_70C4E823.png" width="795" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now it takes 348ms to execute vs. 259ms using the Future pattern.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;It is still in the 25% – 30% speed increase, but take note about the difference in &lt;em&gt;time&lt;/em&gt;. Before, we saved 34 ms. Now, we saved 89 ms. &lt;/p&gt;

&lt;p&gt;Those are pretty significant numbers, and those are against a very small database that I am running locally, against a database that is on another machine, the results would have been even more dramatic.&lt;/p&gt;</description></item><item><title>Future&amp;lt;T&amp;gt; Queries with HQL and Criteria</title><link>http://nhforge.org/blogs/nhibernate/archive/2009/01/30/futuret_2D00_queries_2D00_with_2D00_hql_2D00_and_2D00_criteria.aspx</link><pubDate>Fri, 30 Jan 2009 16:10:00 GMT</pubDate><guid isPermaLink="false">45f813f2-f1c4-4eda-a619-288e3cadc793:158</guid><dc:creator>darioquintana</dc:creator><description>&lt;p&gt;A few days ago Oren Eini and Davy Brion were working in a new feature for NH 2.1 (no a release yet) called Future, in the &lt;i&gt;ICriteria&lt;/i&gt; API. You can see and explanation of the job &lt;a href="http://nhforge.org/blogs/nhibernate/archive/2009/01/25/nhibernate-and-future-queries.aspx"&gt;here&lt;/a&gt;. Now I&amp;rsquo;ve committed a complement to enable that use into the &lt;i&gt;IQuery&lt;/i&gt; API, for those who prefer to use HQL.&lt;/p&gt;
&lt;p&gt;What is Future Query anyway? Future are queries that are kept, waiting to be executed as a group in just one roundtrip, making use of an underlying NHibernate feature: &lt;i&gt;MultiCriteria/MultiQuery&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s have a look to this simple piece of code. You can see both queries sentences, and both are executed in that sentence point against the database producing 2 roundtrips to the database. Nothing weird about this, but what if we can just execute the queries in just one roundtrip?&lt;/p&gt;
&lt;p&gt;&lt;img src="http://darioquintana.com.ar/files/future01.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;And now, using Future we can hold the execution, in this case just two, but we can hold how many queries we need. &lt;/p&gt;
&lt;p&gt;Where is the trick? &lt;i&gt;Future&lt;/i&gt; method is returning a delayed enumerable implementation, that&amp;rsquo;s all. When you iterate the enumerable (with a &lt;i&gt;foreach&lt;/i&gt; for example), it detects and execute all the queries using a NHibernate-MultiQuery command (could be a MultiCriteria, it depends what we are using). But we don&amp;rsquo;t need to know nothing about the underlying implementation, just the concept.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://darioquintana.com.ar/files/future02.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;In other terms, this is what happens behind the scenes:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://darioquintana.com.ar/files/future03.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;But what if we want to retrieve an entity or a scalar ? This is too simple for an IEnumerable. Thanks to Davy Brion we have another feature called FutureValue. The mechanism is the same as Future, but instead of expect a IEnumerable, we obtain a single value (an entity or a scalar).&lt;/p&gt;
&lt;p&gt;&lt;img src="http://darioquintana.com.ar/files/future04.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note&lt;/b&gt;: examples adapted from Davy Brion posts &lt;a href="http://davybrion.com/blog/2009/01/nhibernate-and-future-queries/"&gt;[1]&lt;/a&gt; and &lt;a href="http://davybrion.com/blog/2009/01/nhibernate-and-future-queries-part-2/"&gt;[2]&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>NHibernate and Future Queries</title><link>http://nhforge.org/blogs/nhibernate/archive/2009/01/25/nhibernate-and-future-queries.aspx</link><pubDate>Sun, 25 Jan 2009 12:08:00 GMT</pubDate><guid isPermaLink="false">45f813f2-f1c4-4eda-a619-288e3cadc793:151</guid><dc:creator>DavyBrion</dc:creator><description>&lt;p&gt;As some of you already know, i&amp;#39;m a big fan of avoiding excessive roundtrips by batching queries and/or service calls.  For NHibernate, i wrote the &lt;a href="http://davybrion.com/blog/2008/06/the-query-batcher/"&gt;QueryBatcher&lt;/a&gt; class which makes this pretty easy to do.  Ayende recently added a much easier approach for this to NHibernate.  
&lt;/p&gt;
&lt;p&gt;Take a look at the following code:
&lt;code&gt;

&lt;/code&gt;&lt;/p&gt;
&lt;div class="cf"&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;using&lt;/span&gt; (&lt;span class="cb2"&gt;ISession&lt;/span&gt; session = sessionFactory.OpenSession())&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb3"&gt;// this executes the first query&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;var&lt;/span&gt; categories = session.CreateCriteria(&lt;span class="cb1"&gt;typeof&lt;/span&gt;(&lt;span class="cb2"&gt;ProductCategory&lt;/span&gt;)).List();&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb3"&gt;// this executes the second query&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;var&lt;/span&gt; suppliers = session.CreateCriteria(&lt;span class="cb1"&gt;typeof&lt;/span&gt;(&lt;span class="cb2"&gt;Supplier&lt;/span&gt;)).List();&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;foreach&lt;/span&gt; (&lt;span class="cb1"&gt;var&lt;/span&gt; category &lt;span class="cb1"&gt;in&lt;/span&gt; categories)&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb3"&gt;// do something&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;foreach&lt;/span&gt; (&lt;span class="cb1"&gt;var&lt;/span&gt; supplier &lt;span class="cb1"&gt;in&lt;/span&gt; suppliers)&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb3"&gt;// do something&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;

This is a really trivial example, but it should be more than sufficient.  It simply executes two very simple queries and loops through the results to do something with each returned entity.  The problem, obviously, is that this hits the database twice while there really is no good reason for doing so.
&lt;/p&gt;
&lt;p&gt;With the new Future feature we can rewrite that code like this:
&lt;code&gt;

&lt;/code&gt;&lt;/p&gt;
&lt;div class="cf"&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;using&lt;/span&gt; (&lt;span class="cb2"&gt;ISession&lt;/span&gt; session = sessionFactory.OpenSession())&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb3"&gt;// this creates the first query&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;var&lt;/span&gt; categories = session.CreateCriteria(&lt;span class="cb1"&gt;typeof&lt;/span&gt;(&lt;span class="cb2"&gt;ProductCategory&lt;/span&gt;)).Future&amp;lt;&lt;span class="cb2"&gt;ProductCategory&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb3"&gt;// this creates the second query&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;var&lt;/span&gt; suppliers = session.CreateCriteria(&lt;span class="cb1"&gt;typeof&lt;/span&gt;(&lt;span class="cb2"&gt;Supplier&lt;/span&gt;)).Future&amp;lt;&lt;span class="cb2"&gt;Supplier&lt;/span&gt;&amp;gt;();&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb3"&gt;// this causes both queries to be sent in ONE roundtrip&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;foreach&lt;/span&gt; (&lt;span class="cb1"&gt;var&lt;/span&gt; category &lt;span class="cb1"&gt;in&lt;/span&gt; categories)&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb3"&gt;// do something&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb3"&gt;// this doesn&amp;#39;t do anything because the suppliers have already been loaded&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;foreach&lt;/span&gt; (&lt;span class="cb1"&gt;var&lt;/span&gt; supplier &lt;span class="cb1"&gt;in&lt;/span&gt; suppliers)&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb3"&gt;// do something&lt;/span&gt;&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;

Apart from the comments, did you spot the difference? Instead of calling ICriteria&amp;#39;s List method (which causes the query to be executed immediately), we call ICriteria&amp;#39;s Future method.  This returns an IEnumerable of the type you provided to the Future method.  And this is where it gets interesting.  Instead of executing the queries immediately, the queries are added to an instance of NHibernate&amp;#39;s already existing MultiCriteria class.  Only once you enumerate through one of the retrieved IEnumerables will all the (queued) Future queries be executed, in a single roundtrip.  Once they are executed, their result is final (as in: enumerating through the IEnumerable will not cause the query to be executed again).
&lt;/p&gt;
&lt;p&gt;The example used here is obviously very trivial, but you can use this with any ICriteria so you can very easily start batching your complex queries as well.  The kind of query doesn&amp;#39;t really matter, as long as it&amp;#39;s an ICriteria instance.
&lt;/p&gt;
&lt;p&gt;
This feature will be available in NHibernate 2.1, or if you&amp;#39;re using the trunk you can use it starting with revision 3999.&lt;/p&gt;</description></item></channel></rss>