<?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>Andrey Shchekin &#187; NHibernate</title>
	<atom:link href="http://blog.ashmind.com/category/net/nhibernate/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ashmind.com</link>
	<description></description>
	<lastBuildDate>Mon, 15 Mar 2010 18:00:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Projecting unmapped Ids with Linq-to-NHibernate</title>
		<link>http://blog.ashmind.com/2009/11/05/projecting-unmapped-ids-with-linq-to-nhibernate/</link>
		<comments>http://blog.ashmind.com/2009/11/05/projecting-unmapped-ids-with-linq-to-nhibernate/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 17:46:50 +0000</pubDate>
		<dc:creator>Andrey Shchekin</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[NHibernate.Linq]]></category>

		<guid isPermaLink="false">http://blog.ashmind.com/?p=80</guid>
		<description><![CDATA[There are situations when you do not need to get the fully tracked entities using NHibernate &#8212; you know you wouldn&#8217;t ever edit them and need minimum overhead for this specific scenario. One example is AJAX auto-completion. On the other hand, if you are as obsessed with architectural purity as me, you probably do not [...]]]></description>
			<content:encoded><![CDATA[<p>There are situations when you do not need to get the fully tracked entities using NHibernate &#8212; you know you wouldn&#8217;t ever edit them and need minimum overhead for this specific scenario. One example is AJAX auto-completion. On the other hand, if you are as obsessed with architectural purity as me, you probably <a href="http://stackoverflow.com/questions/860200/ddd-primary-keys-ids-and-orms-for-example-nhibernate">do not have Id properties in your entities</a>, since they are artefacts of (relational) DBs.</p>
<style type="text/css">
.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; }
</style>
<p>So there is the question: in UI layer we want to do
<pre class="csharpcode">repository.Query().Select(x =&gt; <span class="kwrd">new</span> ListItem { Key = x.Id, Name = x.Name })</pre>
<p> But there are no &#8220;Id&#8221; properties in our entities. How can we do this (without returning to the dark ages of untyped criteria)?</p>
<p>There is a very simple (and working) answer. Let&#8217;s start with how I do it for individual entities. When I need a key/id in the UI to identify the entity between requests, I use repository.GetKey(entity), which internally calls session.GetIdentifier(entity). Simple and not intrusive into domain logic. Now,
<pre class="csharpcode inline">repository.Query().Select(x =&gt; <span class="kwrd">new</span> ListItem { Key = GetKey(x), Name = x.Name })</pre>
<p> is obviously impossible, since HQL/DB can not understand GetKey call.</p>
<p>Ok, so the solution is to pre-process the call before Linq-to-NHibernate and replace GetKey call with reference to fake property named &#8220;id&#8221;, which is a magic name NHibernate understands as identifier reference. Linq-to-NHibernate even provides public expression visitor, so it was trivial to create KeyMethodToIdRewritingVisitor (the fake PropertyInfo took most effort, which had to have some stuff to fool Expression.Property).</p>
<p>You can get resulting code below.<br />
It is not perfect, but it works and flaws are really easy to polish out.</p>
<ol>
<li><a href='http://blog.ashmind.com/wp-content/uploads/2009/11/Repository.cs'>Repository</a></li>
<li><a href='http://blog.ashmind.com/wp-content/uploads/2009/11/KeyMethodToIdRewritingVisitor.cs'>KeyMethodToIdRewritingVisitor</a></li>
<li><a href='http://blog.ashmind.com/wp-content/uploads/2009/11/KeyEnabledQueryProvider.cs'>KeyEnabledQueryProvider</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.ashmind.com/2009/11/05/projecting-unmapped-ids-with-linq-to-nhibernate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom mapping for NHibernate.Search</title>
		<link>http://blog.ashmind.com/2009/10/26/custom-mapping-for-nhibernate-search/</link>
		<comments>http://blog.ashmind.com/2009/10/26/custom-mapping-for-nhibernate-search/#comments</comments>
		<pubDate>Mon, 26 Oct 2009 15:04:03 +0000</pubDate>
		<dc:creator>Andrey Shchekin</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[NHibernate.Search]]></category>

		<guid isPermaLink="false">http://blog.ashmind.com/?p=66</guid>
		<description><![CDATA[Recently I had a need for fuzzy search in one of my projects. Since I was using NHibernate, NHibernate.Search (Lucene.NET-based) seemed like a good choice. However, there was one limitation &#8212; NHSearch required custom attributes for its mapping. That was suboptimal. I had to reference NHSearch from domain entities class, I had to add Id [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I had a need for fuzzy search in one of my projects. Since I was using NHibernate, NHibernate.Search (Lucene.NET-based) seemed like a good choice. However, there was one limitation &#8212; NHSearch required custom attributes for its mapping.</p>
<p>That was suboptimal. I had to reference NHSearch from domain entities class, I had to add Id property to my entities to map NHSearch [DocumentId]. Fortunately, it was a free time project, so I decided to take a break from it and fix the NHSearch mapping.</p>
<p>Some days later, the patch <a href="http://groups.google.com/group/nhcdevs/browse_thread/thread/d00f2476d3792abb">was in NHSearch trunk</a>.</p>
<p>So, while there are no new built-in mappings except the attribute one, it is now possible to create a mapping manually. Here is a simple sample mapping that indexes Title property of Book entity:</p>
<style type="text/css">
.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; }</style>
<pre class="csharpcode">
<span class="kwrd">using</span> NHibernate.Cfg;
<span class="kwrd">using</span> NHibernate.Engine;
<span class="kwrd">using</span> NHibernate.Properties;
<span class="kwrd">using</span> NHibernate.Search.Bridge;
<span class="kwrd">using</span> NHibernate.Search.Mapping;

<span class="kwrd">internal</span> <span class="kwrd">class</span> CustomSearchMapping : ISearchMapping {
    <span class="kwrd">public</span> ICollection&lt;DocumentMapping&gt; Build(Configuration cfg) {
        var bookMapping = <span class="kwrd">new</span> DocumentMapping(<span class="kwrd">typeof</span>(Book)) {
            DocumentId = <span class="kwrd">new</span> DocumentIdMapping(<span class="str">&quot;Id&quot;</span>, BridgeFactory.INTEGER, <span class="kwrd">null</span>),
            Fields = { MapField&lt;Book&gt;(book =&gt; book.Title) }
        };

        <span class="kwrd">return</span> <span class="kwrd">new</span> List&lt;DocumentMapping&gt; { bookMapping };
    }

    <span class="kwrd">private</span> FieldMapping MapField&lt;T&gt;(Expression&lt;Func&lt;T, <span class="kwrd">object</span>&gt;&gt; propertyReference) {
        var property = (PropertyInfo)((MemberExpression)propertyReference.Body).Member;

        var getter = <span class="kwrd">new</span> BasicPropertyAccessor.BasicGetter(<span class="kwrd">typeof</span>(T), property, property.Name);
        var bridge = BridgeFactory.GuessType(property.Name, property.PropertyType, <span class="kwrd">null</span>, <span class="kwrd">null</span>);

        <span class="kwrd">return</span> <span class="kwrd">new</span> FieldMapping(property.Name, bridge, getter);
    }
}</pre>
<p>That&#8217;s something that will hopefully get better in time (notice required call to BridgeFactory.GuessType with nulls, that one thing I haven&#8217;t yet got to fix).<br />
But this works, and this does not require attributes (and this does not require reflection at all, actually, you can write your own IGetter with any kind of logic).</p>
<p>One more thing &#8212; the &#8220;Id&#8221; parameter to DocumentIdMapping is how the Id field will be named in index, not your identifier property name.<br />
There is also additional parameter to DocumentIdMapping that specifies property name, but in most scenarios it should just work, even if the identifier is not mapped.</p>
<p>To enable this custom mapping, add the following to your nhsearch.cfg.xml or web.config:
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">property</span> <span class="attr">name</span><span class="kwrd">="hibernate.search.mapping"</span><span class="kwrd">&gt;</span>Sample.Repositories.CustomSearchMapping, Sample.Repositories<span class="kwrd">&lt;/</span><span class="html">property</span><span class="kwrd">&gt;</span></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.ashmind.com/2009/10/26/custom-mapping-for-nhibernate-search/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

