<?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>Software Warlock &#187; Object-relational mapping</title>
	<atom:link href="http://softwareblog.morlok.net/tag/object-relational-mapping/feed/" rel="self" type="application/rss+xml" />
	<link>http://softwareblog.morlok.net</link>
	<description></description>
	<lastBuildDate>Sat, 24 Dec 2011 16:06:59 +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>Mapping Enums to custom strings in NHibernate</title>
		<link>http://softwareblog.morlok.net/2009/07/02/mapping-enums-to-custom-strings-in-nhibernate/</link>
		<comments>http://softwareblog.morlok.net/2009/07/02/mapping-enums-to-custom-strings-in-nhibernate/#comments</comments>
		<pubDate>Fri, 03 Jul 2009 03:16:09 +0000</pubDate>
		<dc:creator>Warlock</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Enum]]></category>
		<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[Object-relational mapping]]></category>
		<category><![CDATA[ORM]]></category>

		<guid isPermaLink="false">http://softwareblog.morlok.net/?p=294</guid>
		<description><![CDATA[Many times when working with a legacy relation model and a newly developed C# object model that sits on top of the relational model, you may need to map enum values to/from arbitrary strings in the database using NHibernate. For &#8230;<p class="read-more"><a href="http://softwareblog.morlok.net/2009/07/02/mapping-enums-to-custom-strings-in-nhibernate/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>
Many times when working with a legacy relation model and a newly developed C# object model that sits on top of the relational model, you may need to map enum values to/from arbitrary strings in the database using NHibernate.
</p>
<p>
For example, suppose you have a a work order object that three possible states: request, approved, denied.  To represent this, you might use the following enum:
</p>
<pre name="code" class="c#">
enum WorkRequestState
{
    Request,
    Approved,
    Denied
};
</pre>
<p>But let&#8217;s assume that the legacy relational model has represented these values as strings: <tt>REQ</tt>, <tt>APR</tt>, <tt>DEN</tt>.  You can&#8217;t change the values for the relational model, and you certainly don&#8217;t want to use these values in your enum because they are not as readable as the values shown above.</p>
<p>By default, NHibernate will automatically convert you enum to a string value that matches the name of the enum values if the table field a string, or it will convert to the integer value for the enum options if the table field is an integer.</p>
<p>To do the above custom mapping we must implement a custom NHibernate type.</p>
<p>First, create a new class that inherits <tt>NHibernate.Type.EnumStringType</tt>.  In your constructor, pass the type of the enum you are handling, and the maximum number of characters that the enum values will be to the base class constructor:</p>
<pre name="code" class="c#">
class WorkRequestStateEnumStringType : NHibernate.Type.EnumStringType
{
    public WorkRequestStateEnumStringType()
        : base( typeof(WorkRequestState), 3)
    {
    }
    ...
}
</pre>
<p>Next, override the <tt>GetValue(...)</tt> method to map the enum value to the equivalent string.</p>
<pre name="code" class="c#">
public override object GetValue(object enm)
{
	if( null == enm )
		return String.Empty;

	switch( (WorkRequestState)enm )
	{
		case WorkRequestState.Request	: return "REQ";
		case WorkRequestState.Approved	: return "APR";
		case WorkRequestState.Denied	: return "DEN";
		default : throw new ArgumentException("Invalid WorkRequestState.");
	}
}
</pre>
<p>Override the <tt>GetInstance(...)</tt> method to map a string value to the equivalent enum value:</p>
<pre name="code" class="c#">
public override object GetInstance(object code)
{
	code = code.ToUpper();

	if( "REQ".Equals(code) )
		return WorkRequestState.Request;
	else if( "APR".Equals(code) )
		return WorkRequestState.Approved;
	else if( "DEN".Equals(code) )
		return WorkRequestState.Denied;

	throw new ArgumentException(
		"Cannot convert code '" + code + "' to WorkRequestState.");
}
</pre>
<p>Finally, in the NHibernate mapping file, specify the property&#8217;s type as the derived <tt>EnumStringType</tt> class.</p>
<pre name="code" class="xml">
&lt;class name="WorkRequest" table="work_request_table"&gt;
  &lt;property
    name="Status"
    column="status_field"
    type="my.namespace. WorkRequestStateEnumStringType, MyAssembly" /&gt;
  ...
&lt;class&gt;
</pre>
<p>Note that when specifying this type, you must use the <a href="http://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname.aspx">assembly-qualified name</a> because the NHibernate code doing the mapping is in a separate assembly from the type you created.</p>
<p>This information has been derived from Jeremy Miller&#8217;s original post <a href="http://codebetter.com/blogs/jeremy.miller/archive/2006/02/20/138732.aspx">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://softwareblog.morlok.net/2009/07/02/mapping-enums-to-custom-strings-in-nhibernate/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

