<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Martijn Boland &#187; NHibernate</title>
	<atom:link href="http://blogs.taiga.nl/martijn/tag/nhibernate/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.taiga.nl/martijn</link>
	<description>New adventures in .NET</description>
	<lastBuildDate>Wed, 25 Jan 2012 22:27:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Entity Framework 4 tips for NHibernate users</title>
		<link>http://blogs.taiga.nl/martijn/2011/12/15/entity-framework-4-tips-for-nhibernate-users/</link>
		<comments>http://blogs.taiga.nl/martijn/2011/12/15/entity-framework-4-tips-for-nhibernate-users/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 09:25:25 +0000</pubDate>
		<dc:creator>martijn</dc:creator>
				<category><![CDATA[O/R mapping]]></category>
		<category><![CDATA[Entity Framework]]></category>
		<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://blogs.taiga.nl/martijn/?p=212</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://blogs.taiga.nl/martijn/2011/12/15/entity-framework-4-tips-for-nhibernate-users/' addthis:title='Entity Framework 4 tips for NHibernate users '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>The last few weeks, I have worked on a project that uses Entity Framework 4 Code First (let’s call it EF from now). Normally, I use NHibernate for my OR-mapping needs and although EF works almost the same conceptually, there are differences. This post is about some of the issues that an NHibernate user can <a href="http://blogs.taiga.nl/martijn/2011/12/15/entity-framework-4-tips-for-nhibernate-users/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://blogs.taiga.nl/martijn/2011/12/15/entity-framework-4-tips-for-nhibernate-users/' addthis:title='Entity Framework 4 tips for NHibernate users '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>The last few weeks, I have worked on a project that uses <a href="http://msdn.microsoft.com/en-us/data/aa937723">Entity Framework 4 Code First</a> (let’s call it EF from now). Normally, I use <a href="http://nhforge.org/">NHibernate</a> for my OR-mapping needs and although EF works almost the same conceptually, there are differences. This post is about some of the issues that an NHibernate user can expect when working with EF. </p>
<h3>Many to one associations and introduce a foreign key property</h3>
<p>Let’s say it bluntly: EF supports <a href="http://blogs.msdn.com/b/efdesign/archive/2009/03/16/foreign-keys-in-the-entity-framework.aspx">Foreign Key associations</a>&#160; (foreign key id’s in your entities, besides many to one associations)&#160; and you better use them, or you’ll experience a lot of pain. I started to model my entities with ‘proper’ object references but ran into 2 problems:</p>
<ul>
<li>Filtering in collection properties causes select n+1 issues. So forget:      <br /> 
<pre class="brush: csharp;">Order.OrderLines.Where(ol =&gt; ol.Product.Id == productId)</pre>
<p>but do: </p>
<p></p>
<pre class="brush: csharp;">Order.OrderLines.Where(ol =&gt; ol.ProductId == productId)</pre>
<p>to filter a collection property because the first will load all product instances; </li>
<li>When you override Equals() and GetHashCode()in your entities to use only the ID for object equality, you can assign an empty object with only the ID set as reference property in NHibernate but EF doesn’t fall for this trick. This is can be very useful, for example when setting references from a dropdownlist where you only have an ID of the referenced object. </li>
</ul>
<p>It seems that EF just doesn’t leverage proxies like NHibernate does so it needs to have the actual object instance to do things instead of just the proxy.<br />
  <br />The good thing however is that when you’re having both a foreign key ID property and an object reference in EF, these are synced automatically and only one column will be generated in the database and the only real issue is a little pollution of your entity.</p>
<h3>Object reference not set to an instance of an object</h3>
<p>So you’ve created a nice object graph and saved it in the database. Then after fetching the object graph back, some of the referenced objects are null even when the ID’s of the references are nicely sitting there in the database. WTF???<br />
  <br />Well, EF doesn’t automatically load a referenced object unless it’s marked as virtual (lazy) or loaded explicitly via Include(). If you forget both, you’ll end up with the NullReferenceExceptions.</p>
<h3>No Dictionary collection mapping</h3>
<p>This is something not many people complain about, but I really miss the option to map dictionaries like Map in NHibernate. Also, NHibernate’s List mappings are not supported. </p>
<h3>Cascade is a big black box</h3>
<p>EF doesn’t have a way to specify how changes in your entity are cascaded into related entities. I’m not sure if this is a good or a bad thing. On one hand I miss having control over this, but on the other hand EF seemed to do well without setting anything.<br />
  <br />Out of the box, EF code first generates CASCADE&#160; DELETE database constraints on required associations but when your model gets only a little bit complex, you’ll get errors like “Introducing FOREIGN KEY constraint on table may cause cycles or multiple cascade paths”. Fortunately, you can turn this off in your DbContext:</p>
<pre class="brush: csharp;">protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // Remove cascade delete convention because it causes trouble when generating the DB.
    modelBuilder.Conventions.Remove&lt;OneToManyCascadeDeleteConvention&gt;();

    base.OnModelCreating(modelBuilder);
}</pre>
<h3>Explicitly set state when attaching objects to the DbContext</h3>
<p>In NHibernate you can simply update an object that isn’t associated with a Session via Session.Update(). EF can do the same via Attach() but you must not forget to explicitly set the object state to modified, otherwise no updates occur:</p>
<pre class="brush: csharp;">dbContext.Customers.Attach(customer);
dbContext.Entry(customer).State = EntityState.Modified;
dbContext.SaveChanges();</pre>
<h3>More?</h3>
<p>Please leave a comment if you want to share your own experiences.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.taiga.nl/martijn/2011/12/15/entity-framework-4-tips-for-nhibernate-users/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cuyahoga 2.0 Alpha released</title>
		<link>http://blogs.taiga.nl/martijn/2009/12/12/cuyahoga-2-0-alpha-released/</link>
		<comments>http://blogs.taiga.nl/martijn/2009/12/12/cuyahoga-2-0-alpha-released/#comments</comments>
		<pubDate>Sat, 12 Dec 2009 15:32:51 +0000</pubDate>
		<dc:creator>martijn</dc:creator>
				<category><![CDATA[Cuyahoga]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Castle]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://blogs.taiga.nl/martijn/2009/12/12/cuyahoga-2-0-alpha-released/</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://blogs.taiga.nl/martijn/2009/12/12/cuyahoga-2-0-alpha-released/' addthis:title='Cuyahoga 2.0 Alpha released '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>Just a little post to let you know that I released the first Alpha of the next generation of the Cuyahoga CMS yesterday. For the people who don’t know Cuyahoga: it’s a .NET CMS that uses lots of Open Source components like NHibernate, Castle Windsor and Lucene.NET. Although not as polished as Umbraco or Dotnetnuke, <a href="http://blogs.taiga.nl/martijn/2009/12/12/cuyahoga-2-0-alpha-released/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://blogs.taiga.nl/martijn/2009/12/12/cuyahoga-2-0-alpha-released/' addthis:title='Cuyahoga 2.0 Alpha released '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>Just a little post to let you know that I released the first Alpha of the next generation of the <a href="http://cuyahoga-project.org">Cuyahoga</a> CMS yesterday. For the people who don’t know Cuyahoga: it’s a .NET CMS that uses lots of Open Source components like NHibernate, Castle Windsor and Lucene.NET. Although not as polished as <a href="http://umbraco.org" target="_blank">Umbraco</a> or <a href="http://www.dotnetnuke.com" target="_blank">Dotnetnuke</a>, I think it still shines when doing custom module and template development.</p>
<p>Development has been a long journey. Already back in 2006 we started development for the 2.0 version. In that time most of the work was done by Max Gaerber. He did a fantastic job in the design of the generic handling of content items.</p>
<p>Then somewhere in 2007 we started the new admin with Castle Monorail, did a spike with the first ASP.NET MVC, changed back to Monorail and finally changed to ASP.NET MVC again. The switch from ASP.NET WebForms to MVC for the site admin allowed us to do some pretty advanced AJAX stuff. The result is still a little rough around the edges, but it’s usable for experimental purposes. </p>
<p>Download it at <a title="http://sourceforge.net/projects/cuyahoga/files/" href="http://sourceforge.net/projects/cuyahoga/files/">http://sourceforge.net/projects/cuyahoga/files/</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.taiga.nl/martijn/2009/12/12/cuyahoga-2-0-alpha-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>One year after the Entity Framework Vote of No Confidence&#8230;</title>
		<link>http://blogs.taiga.nl/martijn/2009/09/24/one-year-after-the-entity-framework-vote-of-no-confidence/</link>
		<comments>http://blogs.taiga.nl/martijn/2009/09/24/one-year-after-the-entity-framework-vote-of-no-confidence/#comments</comments>
		<pubDate>Thu, 24 Sep 2009 15:52:07 +0000</pubDate>
		<dc:creator>martijn</dc:creator>
				<category><![CDATA[O/R mapping]]></category>
		<category><![CDATA[Entity Framework]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://blogs.taiga.nl/martijn/2009/09/24/one-year-after-the-entity-framework-vote-of-no-confidence/</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://blogs.taiga.nl/martijn/2009/09/24/one-year-after-the-entity-framework-vote-of-no-confidence/' addthis:title='One year after the Entity Framework Vote of No Confidence&#8230; '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>About a year ago, a few people (called by some as ‘The NHibernate Mafia’) wrote a vote of no confidence against the Microsoft ADO.NET Entity Framework (EF), mainly because a big influential company like Microsoft was releasing an inferior tool set. See the text of the petition for the detailed reasoning. My initial thoughts were <a href="http://blogs.taiga.nl/martijn/2009/09/24/one-year-after-the-entity-framework-vote-of-no-confidence/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://blogs.taiga.nl/martijn/2009/09/24/one-year-after-the-entity-framework-vote-of-no-confidence/' addthis:title='One year after the Entity Framework Vote of No Confidence&hellip; '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>About a year ago, a few people (called by some as ‘The NHibernate Mafia’) wrote a <a href="http://efvote.wufoo.com/forms/ado-net-entity-framework-vote-of-no-confidence/" target="_blank">vote of no confidence</a> against the Microsoft ADO.NET Entity Framework (EF), mainly because a big influential company like Microsoft was releasing an inferior tool set. See the <a href="http://efvote.wufoo.com/forms/ado-net-entity-framework-vote-of-no-confidence/" target="_blank">text of the petition</a> for the detailed reasoning. </p>
<p>My initial thoughts were ‘why worry, there are plenty alternatives like <a href="http://nhforge.org" target="_blank">NHibernate</a>, <a href="http://www.llblgen.com" target="_blank">LLBLGen Pro</a> or <a href="http://msdn.microsoft.com/en-us/library/bb425822.aspx" target="_blank">LINQ to SQL</a>’ and although I agree with the content of the vote of no confidence, I decided not to sign. That was until realized that as a contractor, you often have to confirm to the technology that the customer has adopted, so it’s to be expected that a lot of future projects have EF as their O/R mapping layer because ‘Microsoft says it’s the way to do data access’. I signed and yes, it’s the selfish me that made me do it.</p>
<p>So now we’re one year later and I just started on a new contract where EF is being used and as I already feared one year ago things are not pretty. The previous developers seem to have struggled a lot, which resulted in poor performance and lots of workarounds.</p>
<p>And you know what: I don’t blame EF itself or the developers but only Microsoft marketing for labeling the Entity Framework as the ‘preferred magic way to do data access’ and all the surrounding blah of future products that will build on EF so people blindly take it as their weapon of choice.</p>
<p>Sorry for this somewhat negative post, but I had to write this off.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.taiga.nl/martijn/2009/09/24/one-year-after-the-entity-framework-vote-of-no-confidence/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>New adventures under medium trust</title>
		<link>http://blogs.taiga.nl/martijn/2009/06/24/new-adventures-under-medium-trust/</link>
		<comments>http://blogs.taiga.nl/martijn/2009/06/24/new-adventures-under-medium-trust/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 12:55:33 +0000</pubDate>
		<dc:creator>martijn</dc:creator>
				<category><![CDATA[Castle]]></category>
		<category><![CDATA[Cuyahoga]]></category>
		<category><![CDATA[Lucene.Net]]></category>
		<category><![CDATA[Medium Trust]]></category>
		<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://blogs.taiga.nl/martijn/2009/06/24/new-adventures-under-medium-trust/</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://blogs.taiga.nl/martijn/2009/06/24/new-adventures-under-medium-trust/' addthis:title='New adventures under medium trust '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>Many web hosting companies only allow ASP.NET applications to run under medium trust. This has been a major drawback for Cuyahoga because it required full trust (or better: some libraries require full trust). This has already caused some nasty surprises when people deployed their site to the host to find out it would not run. <a href="http://blogs.taiga.nl/martijn/2009/06/24/new-adventures-under-medium-trust/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://blogs.taiga.nl/martijn/2009/06/24/new-adventures-under-medium-trust/' addthis:title='New adventures under medium trust '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>Many web hosting companies only allow ASP.NET applications to run under medium trust. This has been a major drawback for <a href="http://cuyahoga-project.org">Cuyahoga</a> because it required full trust (or better: some libraries require full trust). This has already caused some nasty surprises when people deployed their site to the host to find out it would not run.</p>
<p>Well, I can finally say that Cuyahoga 2.0 will work under medium trust!</p>
<h3>Castle DynamicProxy</h3>
<p>Last week, someone mentioned on the <a href="http://castle-project.org" target="_blank">Castle</a> <a href="http://groups.google.com/group/castle-project-users" target="_blank">users list</a> that <a href="http://www.castleproject.org/dynamicproxy/index.html" target="_blank">DynamicProxy</a> was supposed to work under medium trust and this immediately triggered me. DynamicProxy had always been the key part that prevented Cuyahoga, <a href="http://nhforge.org/Default.aspx" target="_blank">NHibernate</a>, and lots of other software from running under medium trust because it generates assemblies on the fly and that’s not allowed (at least pre-NET 2.0 SP1).</p>
<p>So, I checked out a fresh version of the Castle trunk, built it with AllowPartiallyTrustedCallers and copied the assemblies to Cuyahoga that was set to run under medium trust.    <br />Unfortunately, still no luck. The dreaded SecurityException showed its yellow screen, but instead of giving up immediately, I took a deep breath and started digging the DynamicProxy sources. The solution was a simple one: DynamicProxy calls <a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.assemblybuilder.definedynamicmodule.aspx" target="_blank">AssemblyBuilder.DefineDynamicModule</a> and used the overload that generates debug symbols. Changing that to not generate the debug symbols anymore made it work under medium trust! I send a patch to the Castle guys and lets hope it can be incorporated. This allows NHibernate to run under medium trust without turning off <a href="http://nhforge.org/wikis/howtonh/run-in-medium-trust.aspx" target="_blank">lazy-load on class mappings</a> or using a special <a href="http://blechie.com/WPierce/archive/2008/02/17/Lazy-Loading-with-nHibernate-Under-Medium-Trust.aspx" target="_blank">proxy generator</a>.</p>
<p>One caveat: the Castle trunk requires .NET 3.5, so we can’t fix it for the 1.6.x branch of Cuyahoga which is .NET 2.0. </p>
<h3>Lucene.Net</h3>
<p>Second, <a href="http://incubator.apache.org/lucene.net/" target="_blank">Lucene.Net</a> didn’t work under medium trust and boy, that was easy to fix: a single call was made to a relative file path, which is not allowed. Changed that to use the full path and it worked. <a href="http://issues.apache.org/jira/browse/LUCENENET-169" target="_blank">Submitted a patch</a> and I hope they will accept it.</p>
<h3></h3>
<h3>Cuyahoga</h3>
<p>So, with the libraries working under medium trust, I was ready to roll, at least I thought so. It appeared however that Cuyahoga also did some nasty things that are not allowed under medium trust, such as requesting a HttpModule instance from the appdomain and some file access outside the application root. Fortunately these were easy fixes and now I have everything working just fine under medium trust.</p>
<p>I think, I’ll leave medium trust turned on in the development version to signal issues in an early state.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.taiga.nl/martijn/2009/06/24/new-adventures-under-medium-trust/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>NHibernate criteria queries across multiple many-many associations</title>
		<link>http://blogs.taiga.nl/martijn/2008/11/20/nhibernate-criteria-queries-across-multiple-many-many-associations/</link>
		<comments>http://blogs.taiga.nl/martijn/2008/11/20/nhibernate-criteria-queries-across-multiple-many-many-associations/#comments</comments>
		<pubDate>Thu, 20 Nov 2008 11:31:07 +0000</pubDate>
		<dc:creator>martijn</dc:creator>
				<category><![CDATA[O/R mapping]]></category>
		<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://blogs.taiga.nl/martijn/archive/2008/11/20/nhibernate-criteria-queries-across-multiple-many-many-associations.aspx</guid>
		<description><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://blogs.taiga.nl/martijn/2008/11/20/nhibernate-criteria-queries-across-multiple-many-many-associations/' addthis:title='NHibernate criteria queries across multiple many-many associations '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>Recently, I ran into an issue with NHibernate Criteria queries. The scenario is the following: User has a many-many association with Role and Role has a many-many association with Site. I simply wanted all users that belong to a given site (and a whole slew of other optional parameters, therefore the Criteria query). With hql <a href="http://blogs.taiga.nl/martijn/2008/11/20/nhibernate-criteria-queries-across-multiple-many-many-associations/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<div class="addthis_toolbox addthis_default_style " addthis:url='http://blogs.taiga.nl/martijn/2008/11/20/nhibernate-criteria-queries-across-multiple-many-many-associations/' addthis:title='NHibernate criteria queries across multiple many-many associations '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div><p>Recently, I ran into an issue with NHibernate Criteria queries. The scenario is the following:</p>
<p><a href="http://blogs.taiga.nl/martijn/wp-content/uploads/subtext/WindowsLiveWriter/NHibernatecriteriaqueriesacrossmultiplem_AF7F/double-many-many_4.png"><img style="border: 0pt none;" src="http://blogs.taiga.nl/martijn/wp-content/uploads/subtext/WindowsLiveWriter/NHibernatecriteriaqueriesacrossmultiplem_AF7F/double-many-many_thumb_1.png" border="0" alt="double-many-many" width="642" height="108" /></a></p>
<p>User has a many-many association with Role and Role has a many-many association with Site. I simply wanted all users that belong to a given site (and a whole slew of other optional parameters, therefore the Criteria query).</p>
<p>With hql this is simple:</p>
<div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; font-size: 8pt; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">select distinct u from User u join u.Roles r join r.Sites s <span style="color: #0000ff">where</span> s.Id = :siteId</pre>
</div>
</div>
<p>With a criteria query, it appeared a little bit harder. First I tried this:</p>
<div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; font-size: 8pt; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">ICriteria crit = session.CreateCriteria(<span style="color: #0000ff">typeof</span>(User))</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    .CreateCriteria(<span style="color: #006080">"Roles"</span>) <span style="color: #008000">// traverse into Roles</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        .CreateCriteria(<span style="color: #006080">"Sites"</span>) <span style="color: #008000">// traverse into Sites</span></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            .Add(Expression.Eq(<span style="color: #006080">"Id"</span>, siteId);</pre>
</div>
</div>
<p>Note the absence of the <em>distinct</em> keyword anywhere in the query. A nice Cartesian Product was the result due to the joins on the linking tables. Some googling showed that we can get distinct results with Criteria queries by applying the DistinctRootEntityResultTransformer via Criteria.SetResultTransformer() but that all happens in memory and not in the database query (call me old-fashioned, but I&#8217;d like my database results properly filtered <img src='http://blogs.taiga.nl/martijn/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ).</p>
<p>Finally, I found the solution in using <a href="http://davybrion.com/blog/2008/10/querying-with-nhibernate/" target="_blank">subqueries</a>:</p>
<div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; font-size: 8pt; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">ICriteria crit = session.CreateCriteria(<span style="color: #0000ff">typeof</span>(User));</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">DetachedCriteria roleIdsForSite = DetachedCriteria.For(<span style="color: #0000ff">typeof</span> (Role))</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    .SetProjection(Projections.Property(<span style="color: #006080">"Id"</span>))</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    .CreateCriteria(<span style="color: #006080">"Sites"</span>, <span style="color: #006080">"site"</span>)</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    .Add(Expression.Eq(<span style="color: #006080">"site.Id"</span>, siteId.Value));</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">DetachedCriteria userIdsForRoles = DetachedCriteria.For(<span style="color: #0000ff">typeof</span>(User))</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    .SetProjection(Projections.Distinct(Projections.Property(<span style="color: #006080">"Id"</span>)))</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    .CreateCriteria(<span style="color: #006080">"Roles"</span>)</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        .Add(Subqueries.PropertyIn(<span style="color: #006080">"Id"</span>, roleIdsForSite));</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">crit.Add(Subqueries.PropertyIn(<span style="color: #006080">"Id"</span>, userIdsForRoles));</pre>
</div>
</div>
<p>Yes, that&#8217;s an insane amount of code to do something that simple, but it works and the generated SQL is highly efficient <img src='http://blogs.taiga.nl/martijn/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Notice the <em>distinct</em> projection in the second DetachedCriteria (userIdsForRoles).</p>
<p>I&#8217;d really appreciate it if somebody has any suggestions for improvement.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.taiga.nl/martijn/2008/11/20/nhibernate-criteria-queries-across-multiple-many-many-associations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

