<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>NHibernate</title>
        <link>http://www.codeofrob.com/category/2.aspx</link>
        <description>Posts about NHibernate</description>
        <language>en-GB</language>
        <copyright>Rob Ashton</copyright>
        <generator>Subtext Version 2.1.2.2</generator>
        <item>
            <title>Sqlite-Csharp and NHibernate</title>
            <link>http://codeofrob.com/archive/2010/06/07/nhibernate-csharp-sqlite.aspx</link>
            <description>&lt;p&gt;Taking a brief  interlude from my RavenDB series, I was doing some work on an internal project tonight with the build scripts and test-runner and I finally got bored of having to deal with un-managed SQLite dependencies with a project which other than that was platform agnostic.&lt;/p&gt;  &lt;p&gt;The problem with having un-managed dependencies in a managed project is that Visual Studio quite frankly sucks at it, you can set up certain projects (in this case the tests) to be x86 only, and remove their Any CPU configuration – but as soon as you add a new project to the solution it decides to re-add the old configuration and potentially break things again. &lt;/p&gt;  &lt;p&gt;This doesn't really rear any problems until you write a build script and things start falling over as your test runner tries to run as an x64 process and tries to load in the x86 dependency, or any number of combinations where this kind of thing can blow up. If it can happen, it will happen and it’s just something I’d rather not deal with.&lt;/p&gt;  &lt;p&gt;So I had a look at &lt;a href="http://code.google.com/p/csharp-sqlite/"&gt;Sqlite-Csharp&lt;/a&gt;, the code is atrocious as far as natively written C# libraries go (that’s not the point though, it’s a *port*), but it looks to be a superb direct-port of a C project (Sqlite) and passes most of the tests that it needs to in order for it to be viable for use in at least our in-memory tests.&lt;/p&gt;  &lt;p&gt;Anyway, you can’t download binaries, so you have to build it – but no changes are required so just do it.&lt;/p&gt;  &lt;p&gt;I’m not going to cover the process of setting up in-memory databases for testing with SQLite as that’s an easily Google-able topic, but there are a few differences between doing it with the unmanaged libraries and with the pure managed libraries.&lt;/p&gt;  &lt;p&gt;This is what my FluentNHibernate configuration looks like:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;Fluently.Configure()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;            .Database(&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;                 SQLiteConfiguration.Standard.ConnectionString(&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;                      x =&amp;gt; x.Is(mConnectionString)).Driver&amp;lt;SqliteDriver&amp;gt;());&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p /&gt;

&lt;p&gt;I’ve had to create a driver to make this work properly as there isn’t one provided as stock in NHibernate, the code for this is as simple as this:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SqliteDriver : ReflectionBasedDriver&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;        &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;        &lt;span class="rem"&gt;/// Initializes a new instance of &amp;lt;see cref="SQLiteDriver"/&amp;gt;.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        &lt;span class="rem"&gt;/// &amp;lt;exception cref="HibernateException"&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        &lt;span class="rem"&gt;/// Thrown when the &amp;lt;c&amp;gt;Community.CsharpSqlite.SQLiteClient&amp;lt;/c&amp;gt; assembly can not be loaded.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        &lt;span class="rem"&gt;/// &amp;lt;/exception&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; SqliteDriver()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;            : &lt;span class="kwrd"&gt;base&lt;/span&gt;(&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;                &lt;span class="str"&gt;"Community.CsharpSqlite.SQLiteClient"&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;                &lt;span class="str"&gt;"Community.CsharpSqlite.SQLiteClient.SqliteConnection"&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;                &lt;span class="str"&gt;"Community.CsharpSqlite.SQLiteClient.SqliteCommand"&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; UseNamedPrefixInSql&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; UseNamedPrefixInParameter&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; NamedPrefix&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;"@"&lt;/span&gt;; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; SupportsMultipleOpenReaders&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; SupportsMultipleQueries&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  41:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p /&gt;

&lt;p&gt;Yeah, not terribly exciting – just add a reference to Community.CsharpSqlite.SQLiteClient and this will work.&lt;/p&gt;

&lt;p&gt;The other major difference is the delimiter between connection string components is a comma and the method of selecting an in-memory database looks different. This is my connection string:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="str"&gt;"uri=file://:memory:,Version=3"&lt;/span&gt;;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;And this is the code I use to create the connection:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; SqliteConnection GetConnection()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (mConnection == &lt;span class="kwrd"&gt;null&lt;/span&gt;) {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;                mConnection = &lt;span class="kwrd"&gt;new&lt;/span&gt; SqliteConnection(mConnectionString);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;                mConnection.Open();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;            }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; mConnection;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        }&lt;/pre&gt;
&lt;/div&gt;

&lt;p /&gt;&lt;style type="text/css"&gt;&lt;![CDATA[

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;And this is therefore the code I use to create a session factory:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;mFactory.OpenSession(GetConnection());&lt;/pre&gt;
&lt;/div&gt;

&lt;div class="csharpcode"&gt; &lt;/div&gt;

&lt;p&gt;&lt;strong&gt;A word of warning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mileage may vary, I had 11 tests from about 300 fail, mostly due to unrecognised types/null values and exceptions that were different in this version of Sqlite, I’m submitting some code fixes for the unrecognised types and null values and modifying my tests to take into account the new exception types.&lt;/p&gt;

&lt;p&gt;Also, I can’t guarantee I’ve done it right, so let me know if I’ve done something stupid.&lt;/p&gt;

&lt;p&gt;All of my tests are now Any CPU and my build process is suddenly a lot simpler, I’ll take the hit of having to submit and change a bit of code in order to get that.&lt;/p&gt;&lt;img src="http://codeofrob.com/aggbug/34.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Rob Ashton</dc:creator>
            <guid>http://codeofrob.com/archive/2010/06/07/nhibernate-csharp-sqlite.aspx</guid>
            <pubDate>Mon, 07 Jun 2010 21:44:31 GMT</pubDate>
            <wfw:comment>http://codeofrob.com/comments/34.aspx</wfw:comment>
            <comments>http://codeofrob.com/archive/2010/06/07/nhibernate-csharp-sqlite.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://codeofrob.com/comments/commentRss/34.aspx</wfw:commentRss>
            <trackback:ping>http://codeofrob.com/services/trackbacks/34.aspx</trackback:ping>
        </item>
        <item>
            <title>Why Linq2NHibernate isn't ready for production use</title>
            <link>http://codeofrob.com/archive/2009/10/22/why-linq2nhibernate-isnt-ready-for-production-use.aspx</link>
            <description>I was quite excited when Ayende announced that he had written a Linq provider for NHibernate which was of &lt;a href="http://ayende.com/Blog/archive/2009/07/26/nhibernate-linq-1.0-released.aspx"&gt;production quality&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
It came with a few caveats, it could only do what criteria currently supported and they hadn't implemented any sort of join support. I considered these to be perfectly reasonable items on the todo list, given that they are actively working on creating a more complete linq provider that does everything people would want it to do.&lt;br /&gt;
&lt;br /&gt;
I do the vast bulk of my queries using the criteria API, written as specifications against thin repositories, and adding a LinqSpecification was a simple task. I decided that given the limitations described above to follow a few simple rules for when I could use a Linq query such as "only use Linq when querying the properties of a single type of object".&lt;br /&gt;
&lt;br /&gt;
Having Linq in my specifications gave some real benefits, such as strong typing and compile time support for checking the properties being queried against. Normally if you change the name of a property on any domain object and forget to update the text in a criteria or hql query you'd only catch this when you ran your unit tests. (Or worse, during product testing/use!)&lt;br /&gt;
&lt;br /&gt;
I was using it quite happily for a week or so until I stopped to review the sql it was generating under the hood for even the simplest of queries.
&lt;p&gt;Consider the following objects:&lt;/p&gt;
&lt;pre class="brush: csharp;" title="code"&gt;    public class Blog
    {
        public virtual int Id
        {
            get;
            protected set;
        }

        public virtual String Name
        {
            get;
            set;
        }
    }

    public class BlogEntry
    {
        public virtual int Id
        {
            get;
            set;
        }

        public virtual Blog Blog
        {
            get;
            set;
        }

        public virtual String Content
        {
            get;
            set;
        }
    }&lt;/pre&gt;
&lt;p&gt;With the following mappings: &lt;/p&gt;
&lt;pre class="brush: csharp;" title="code"&gt;    public class BlogMap : ClassMap&amp;lt;Blog&amp;gt;
    {
        public BlogMap()
        {
            Id(x =&amp;gt; x.Id);
            Map(x =&amp;gt; x.Name).Not.Nullable();
        }
    }

    public class BlogEntryMap : ClassMap&amp;lt;BlogEntry&amp;gt;
    {
        public BlogEntryMap()
        {
            Id(x =&amp;gt; x.Id);
            Map(x =&amp;gt; x.Content).Not.Nullable();
            References(x =&amp;gt; x.Blog).Not.Nullable();
        }
    }&lt;/pre&gt;
&lt;p&gt;Fairly straight forward stuff. Now imagine I have a blog object in hand and I wish to query for all the entries that belong to that blog (We could easily imagine asking this being a query where we ask for the entries from that blog between a certain date range).&lt;br /&gt;
&lt;br /&gt;
The query looks something like this: &lt;/p&gt;
&lt;pre class="brush: csharp;" title="code"&gt;            var linqResults = (
                        from entry in session.Linq&amp;lt;BlogEntry&amp;gt;()
                        where entry.Blog  == blog
                        select entry
                      ).ToList();&lt;/pre&gt;
&lt;br /&gt;
Again, very straight forward - and you'd expect the query to be so as well - so have a look! &lt;br /&gt;
&lt;pre class="brush: sql;" title="code"&gt;SELECT this_.Id as Id1_1_, this_.Content as Content1_1_, this_.Blog_id as Blog3_1_1_, blog1_.Id as Id0_0_, blog1_.Name as Name0_0_ FROM "BlogEntry" this_ left outer join "Blog" blog1_ on t his_.Blog_id=blog1_.Id WHERE this_.Blog_id = @p0;@p0 = 1&lt;/pre&gt;
What WHAAT?!&lt;br /&gt;
&lt;br /&gt;
If you can't see the problem here then go and ask your DBA if you have one, because I can guarantee they'll not be happy if you start littering your specifications with this kind of query. &lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
    &lt;li&gt;Why are we doing a join to the Blog table? We don't need to do a join to the Blog table, we should be comparing the id situated in the BlogEntry table. &lt;/li&gt;
    &lt;li&gt;Why are we bringing back al the information from the blog table as well as the blog entry? Imagine you're bringing back 50 such blog entries - you'd be bringing back 50 identical blog objects too. &lt;/li&gt;
    &lt;li&gt;It's a left outer join too, your DBA is going to hit the roof! (Mine definitely would - you should only be using these where it makes sense to be using them. &lt;/li&gt;
&lt;/ol&gt;
Check out the equivalent Criteria based query:&lt;br /&gt;
           
&lt;pre class="brush: csharp;" title="code"&gt;            var criteria = session.CreateCriteria&amp;lt;BlogEntry&amp;gt;()
                                .Add(Restrictions.Eq("Blog", blog)).List&amp;lt;BlogEntry&amp;gt;();&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Generating the following SQL:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: sql;" title="code"&gt;SELECT this_.Id as Id1_0_, this_.Content as Content1_0_, this_.Blog_id as Blog3_1_0_ FROM "BlogEntry" this_ WHERE this_.Blog_id = @p0;@p0 = 1&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;
Much more sensible.&lt;br /&gt;
&lt;br /&gt;
You might be of the persuasion that you don't really care, and that's acceptable in some cases I guess- but I'm of the opinion that if all of your queries look like the above then you've got some real issues. Our product has to service the needs of some fairly large customers with some fairly heavy load and the system chugging at &lt;span style="FONT-WEIGHT: bold"&gt;all &lt;/span&gt;is going to get us in a lot of trouble. &lt;/p&gt;
&lt;p&gt;Take for example the following (perfectly reasonable) query if our objects were a little more complex.&lt;/p&gt;
&lt;pre class="brush: csharp;" title="code"&gt;            var complexResult = (
                    from entry in session.Linq&amp;lt;BlogEntry&amp;gt;()
                    where entry.Category == category &amp;amp;&amp;amp;  entry.Blog.User == user
                    select entry
                ).ToList();&lt;/pre&gt;
&lt;p&gt;This will generate the following SQL:&lt;/p&gt;
&lt;pre class="brush: sql;" title="code"&gt;SELECT this_.Id as Id1_3_, this_.Content as Content1_3_, this_.Blog_id as Blog3_1_3_, this_.Category_id as Category4_1_3_, blog2_.Id as Id0_0_, blog2_.Name as Name0_0_, blog2_.User_id as User3_0_0_, user3_.Id as Id3_1_, user3_.Name as Name3_1_, category1_.Id as Id2_2_, category1_.Name as Name2_2_ FROM "BlogEntry" this_ left outer join "Blog" blog2_ on this_.Blog_id=blog2_.Id left outer join "User" user3_ on blog2_.User_id=user3_.Id left outer join "Category" category1_ on this_.Category_id=category1_.Id WHERE (this_.Category_id = @p0 and blog2_.User_id = @p1);@p0 = 1, @p1 = 1&lt;/pre&gt;
&lt;p&gt;Every single property of every single referenced object being brought back even though I've only asked for BlogEntry.&lt;/p&gt;
&lt;p&gt;Without trying to sound like a complete arse, this is not the definition of production quality I am familar with! &lt;br /&gt;
&lt;br /&gt;
 I really do look forward to the proper release of Linq2NHibernate, but until then I'm sticking to Hql And Criteria because I can trust them to keep my DBA happy.&lt;/p&gt;
&lt;p /&gt;&lt;hr /&gt;
Technorati tags: &lt;a rel="tag" href="http://technorati.com/tags/NHibernate"&gt;NHibernate&lt;/a&gt;, &lt;a rel="tag" href="http://technorati.com/tags/Linq2NHibernate"&gt;Linq2NHibernate&lt;/a&gt;, &lt;a rel="tag" href="http://technorati.com/tags/Linq"&gt;Linq&lt;/a&gt;, &lt;a rel="tag" href="http://technorati.com/tags/.NET"&gt;.NET&lt;/a&gt;&lt;img src="http://codeofrob.com/aggbug/2.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Rob Ashton</dc:creator>
            <guid>http://codeofrob.com/archive/2009/10/22/why-linq2nhibernate-isnt-ready-for-production-use.aspx</guid>
            <pubDate>Wed, 21 Oct 2009 23:00:00 GMT</pubDate>
            <wfw:comment>http://codeofrob.com/comments/2.aspx</wfw:comment>
            <comments>http://codeofrob.com/archive/2009/10/22/why-linq2nhibernate-isnt-ready-for-production-use.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://codeofrob.com/comments/commentRss/2.aspx</wfw:commentRss>
            <trackback:ping>http://codeofrob.com/services/trackbacks/2.aspx</trackback:ping>
        </item>
    </channel>
</rss>