<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2italianfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss version="2.0"><channel><title>Il blog di Ugo Lattanzi | ASP.NET, MVC, .NET Framework, WCF, WF, NHibernate, Linq, Microsoft</title><link>http://imperugo.tostring.it/</link><description>Il blog personale di Ugo Lattanzi dove potete trovare risorse su ASP.NET, MVC, .NET Framework, WCF, WF, NHibernate, Linq ed eventi sul mondo Microsoft</description><copyright>Ugo Lattanzi</copyright><docs>http://www.rssboard.org/rss-specification</docs><generator>http://dexterblogengine.codeplex.com</generator><language>en-US</language><lastBuildDate>Mon, 16 May 2011 09:50:00 GMT</lastBuildDate><webMaster>imperugo</webMaster><category>ASP.NET</category><category>ASP.NET 2.0</category><category>.aspx</category><category>.ascx</category><category>.NET Framework</category><category>WCF</category><category>Windows Communication Foundation</category><category>Web Services</category><category>NHibernate</category><category>Linq</category><category>IIS</category><category>Windows Server</category><category>Entity Framework</category><category>Active Server Pages</category><category>Architettura</category><category>Scalabilità</category><category>C#</category><category>Microsoft</category><category>Visual Studio .NET</category><category>Web</category><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/imperugo_ORM" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="imperugo_orm" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://add.my.yahoo.com/content?lg=it&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://eur.i1.yimg.com/eur.yimg.com/i/it/my/mioya1.gif">Subscribe with Mio Yahoo!</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.bloglines.com/sub/http://feeds.feedburner.com/imperugo_ORM" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.newsalloy.com/?rss=http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://www.newsalloy.com/subrss3.gif">Subscribe with NewsAlloy</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.yourminis.com/subscribe.aspx?u=http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://www.yourminis.com/images/addtoyourminisbadge.gif">Subscribe with Yourminis.com</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://download.attensa.com/app/get_attensa.html?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://www.attensa.com/blogs/attensa/WindowsLiveWriter/BadgeredintoBadges_10C02/attensa_feed_button5.gif">Subscribe with Attensa for Outlook</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://hub.netomat.net/account/account.autoSubscribe.jspa?urls=http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://www.netomat.net/blogger/images/icon_netomat_feedbutton.gif">Subscribe with netomat Hub</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.flurry.com/pushRssFeed.do?r=fb&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://www.flurry.com/images/flurry_rss_logo2.gif">Subscribe with Flurry</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2Fimperugo_ORM" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><item><title>Gestione dei DateTime ed i vari TimeZone</title><description>&lt;p&gt;Tra le varie problematiche che ho incontrato nello sviluppare &lt;a title="Dexter Blog Engine Official Site" href="http://dexterblogengine.com/" target="_blank"&gt;Dexter&lt;/a&gt;, ce n’è una il cui rimedio è divenuto indispensabile nella maggior parte delle applicazioni, ossia una gestione un po’ più avanzata del DateTime all’interno dell’applicazione.     &lt;br /&gt;Durante la migrazione tra i vari server, ho riscontrato un problema con i vari DateTime di ciascuno di essi; essendo dislocati in aree geografiche diverse, restituivano infatti valori nettamente differenti per via del fuso orario dal server vecchio a quello nuovo.&lt;/p&gt;  &lt;p&gt;Il primo server su cui risiedeva il mio blog era su un provider il cui fuso orario era impostato su &lt;a title="Fuso orario" href="http://it.wikipedia.org/wiki/Fuso_orario#UTC-5_.28EST_-_Eastern_Standard_Time.29" rel="nofollow" target="_blank"&gt;EST&lt;/a&gt;, che differisce di tre ore rispetto all’orario del nuovo server che è impostato sulla &lt;a title="Fuso Orario" href="http://it.wikipedia.org/wiki/Fuso_orario#UTC-8_.28PST_-_Pacific_Standard_Time.29" rel="nofollow" target="_blank"&gt;PST&lt;/a&gt;. Questa differenza ha causato un’errata visualizzazione degli orari dei post sul mio blog, che risultavano sfalzati di tre ore&lt;/p&gt;  &lt;p&gt;Oltre a sistemare tutti i valori memorizzati nel database con una query, ho deciso di affrontare e risolvere il problema in modo da non avere una dipendenza del fuso orario nelle date memorizzate, essendo quindi libero di gestire l’output dell’ora nel TimeZone a me più congeniale.&lt;/p&gt;  &lt;p&gt;Per prima cosa ho realizzato uno UserType per NHibernate che convertisse tutte le date in ingresso verso il databse in formato UTC e, in fase di idratazione della entity, le convertisse nel TimeZone da me configurato. Questa operazione, in codice, si traduce più o meno così:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;[Serializable]
internal class DateTimeUtc : IUserType {
    #region IUserType Members

    /// &amp;lt;summary&amp;gt;
    /// Determines whether the specified &amp;lt;see cref=&amp;quot;System.Object&amp;quot;/&amp;gt; is equal to this instance.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;x&amp;quot;&amp;gt;The &amp;lt;see cref=&amp;quot;System.Object&amp;quot;/&amp;gt; to compare with this instance.&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;y&amp;quot;&amp;gt;The y.&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;
    ///     &amp;lt;c&amp;gt;true&amp;lt;/c&amp;gt; if the specified &amp;lt;see cref=&amp;quot;System.Object&amp;quot;/&amp;gt; is equal to this instance; otherwise, &amp;lt;c&amp;gt;false&amp;lt;/c&amp;gt;.
    /// &amp;lt;/returns&amp;gt;
    public new bool Equals ( object x , object y ) {
        if ( ReferenceEquals ( x , y ) ) {
            return true;
        }
        if ( x == null || y == null ) {
            return false;
        }
        return x.Equals ( y );
    }

    /// &amp;lt;summary&amp;gt;
    /// Returns a hash code for this instance.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;x&amp;quot;&amp;gt;The x.&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;
    /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
    /// &amp;lt;/returns&amp;gt;
    public int GetHashCode ( object x ) {
        return x == null
                   ? typeof ( DateTime ).GetHashCode ( ) + 473
                   : x.GetHashCode ( );
    }

    /// &amp;lt;summary&amp;gt;
    /// Retrieve an instance of the mapped class from a JDBC resultset.
    /// Implementors should handle possibility of null values.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;rs&amp;quot;&amp;gt;a IDataReader&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;names&amp;quot;&amp;gt;column names&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;owner&amp;quot;&amp;gt;the containing entity&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
    /// &amp;lt;exception cref=&amp;quot;T:NHibernate.HibernateException&amp;quot;&amp;gt;HibernateException&amp;lt;/exception&amp;gt;
    public object NullSafeGet ( IDataReader rs , string[] names , object owner ) {
        object obj = NHibernateUtil.DateTime.NullSafeGet ( rs , names[ 0 ] );
        if ( obj == null ) {
            return null;
        }

        var dbValue = ( DateTime ) obj;

        SiteConfiguration configuration = DexterContainer.Resolve &amp;lt;IConfigurationRepository&amp;gt; ( ).Configuration;

        dbValue = configuration != null
                      ? System.TimeZoneInfo.ConvertTimeFromUtc ( dbValue , configuration.TimeZone )
                      : dbValue.ToUniversalTime ( );

        return dbValue;
    }

    /// &amp;lt;summary&amp;gt;
    /// Write an instance of the mapped class to a prepared statement.
    /// Implementors should handle possibility of null values.
    /// A multi-column type should be written to parameters starting from index.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;cmd&amp;quot;&amp;gt;a IDbCommand&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;value&amp;quot;&amp;gt;the object to write&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;index&amp;quot;&amp;gt;command parameter index&amp;lt;/param&amp;gt;
    /// &amp;lt;exception cref=&amp;quot;T:NHibernate.HibernateException&amp;quot;&amp;gt;HibernateException&amp;lt;/exception&amp;gt;
    public void NullSafeSet ( IDbCommand cmd , object value , int index ) {
        if ( value == null ) {
            ( ( IDataParameter ) cmd.Parameters[ index ] ).Value = DBNull.Value;
        }
        else {
            var myValue = ( DateTime ) value;

            SiteConfiguration configuration = DexterContainer.Resolve&amp;lt;IConfigurationRepository&amp;gt; ( ).Configuration;

            if ( configuration != null ) {
                myValue = myValue.Kind == DateTimeKind.Unspecified
                              ? System.TimeZoneInfo.ConvertTimeToUtc ( myValue , configuration.TimeZone )
                              : myValue.ToUniversalTime ( );
            }
            else {
                myValue.ToUniversalTime ( );
            }

            ( ( IDataParameter ) cmd.Parameters[ index ] ).Value = myValue;
        }
    }

    /// &amp;lt;summary&amp;gt;
    /// Return a deep copy of the persistent state, stopping at entities and at collections.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;value&amp;quot;&amp;gt;generally a collection element or entity field&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;a copy&amp;lt;/returns&amp;gt;
    public object DeepCopy ( object value ) {
        return value;
    }

    /// &amp;lt;summary&amp;gt;
    /// During merge, replace the existing (&amp;lt;paramref name=&amp;quot;target&amp;quot;/&amp;gt;) value in the entity
    /// we are merging to with a new (&amp;lt;paramref name=&amp;quot;original&amp;quot;/&amp;gt;) value from the detached
    /// entity we are merging. For immutable objects, or null values, it is safe to simply
    /// return the first parameter. For mutable objects, it is safe to return a copy of the
    /// first parameter. For objects with component values, it might make sense to
    /// recursively replace component values.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;original&amp;quot;&amp;gt;the value from the detached entity being merged&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;target&amp;quot;&amp;gt;the value in the managed entity&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;owner&amp;quot;&amp;gt;the managed entity&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;the value to be merged&amp;lt;/returns&amp;gt;
    public object Replace ( object original , object target , object owner ) {
        return original;
    }

    /// &amp;lt;summary&amp;gt;
    /// Reconstruct an object from the cacheable representation. At the very least this
    /// method should perform a deep copy if the type is mutable. (optional operation)
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;cached&amp;quot;&amp;gt;the object to be cached&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;owner&amp;quot;&amp;gt;the owner of the cached object&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;
    /// a reconstructed object from the cachable representation
    /// &amp;lt;/returns&amp;gt;
    public object Assemble ( object cached , object owner ) {
        return cached;
    }

    /// &amp;lt;summary&amp;gt;
    /// Transform the object into its cacheable representation. At the very least this
    /// method should perform a deep copy if the type is mutable. That may not be enough
    /// for some implementations, however; for example, associations must be cached as
    /// identifier values. (optional operation)
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;value&amp;quot;&amp;gt;the object to be cached&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;a cacheable representation of the object&amp;lt;/returns&amp;gt;
    public object Disassemble ( object value ) {
        return value;
    }

    /// &amp;lt;summary&amp;gt;
    /// The SQL types for the columns mapped by this type.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;&amp;lt;/value&amp;gt;
    public SqlType[] SqlTypes {
        get {
            return new[] {
                new SqlType ( DbType.DateTime )
            };
        }
    }

    /// &amp;lt;summary&amp;gt;
    /// The type returned by &amp;lt;c&amp;gt;NullSafeGet()&amp;lt;/c&amp;gt;
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;&amp;lt;/value&amp;gt;
    public Type ReturnedType {
        get { return typeof ( DateTime ); }
    }

    /// &amp;lt;summary&amp;gt;
    /// Are objects of this type mutable?
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;&amp;lt;/value&amp;gt;
    public bool IsMutable {
        get { return false; }
    }

    #endregion
}&lt;/pre&gt;

&lt;p&gt;Una volta affrontato il problema del salvataggio della data, rimaneva soltanto quello riguardante i filtri delle query che, per i campi DateTime, dovevano effettuare una conversione in formato UTC più o meno in questo modo:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.tostring.it/UserFiles/imperugo/SNAGHTML2d258d7.png" target="_blank"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="SNAGHTML2d258d7" border="0" alt="SNAGHTML2d258d7" src="http://www.tostring.it/UserFiles/imperugo/SNAGHTML2d258d7_thumb.png" width="244" height="158" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Purtroppo mi è capitato più volte di dimenticarmi di effettuare quel ToUniversalDateTime all’assegnazione del parametro di una query, con l’ovvio problema di avere risultati sballati in fase di visualizzazione.&lt;/p&gt;

&lt;p&gt;Fortunatamente con la versione 3.2 di NHibernate è stato rivisto parzialmente il Driver di SqlServer, che ora espone un metodo &amp;quot;AdjustCommand” subito prima dell’ExecuteQuery. Il codice seguente mostra come effettuare automaticamente la conversione dal DateTimeKind.Local al DateTimeKind.Utc:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public class DexterSqlClientDriver : SqlClientDriver {
    
    public override void AdjustCommand ( System.Data.IDbCommand command ) {
        foreach (var parameter in command.Parameters.Cast&amp;lt;SqlParameter&amp;gt; ( ).Where ( x =&amp;gt; x.SqlDbType == SqlDbType.DateTime &amp;amp;&amp;amp; ( x.Value is DateTime ) )) {
            var dateTimeValue = (( DateTime )parameter.Value).ToUniversalTime (  );
            parameter.Value = dateTimeValue;
        }
    }
}&lt;/pre&gt;

&lt;p&gt;A questo punto, il codice di esecuzione della query si semplifica ancor di più poiché il developer non deve sapere, o ricordarsi, che il formato della data sul database è differente, in quanto la conversione avviene in automatico.
  &lt;br /&gt;Il risultato è il seguente:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.tostring.it/UserFiles/imperugo/SNAGHTML2d2e78f.png" target="_blank"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="SNAGHTML2d2e78f" border="0" alt="SNAGHTML2d2e78f" src="http://www.tostring.it/UserFiles/imperugo/SNAGHTML2d2e78f_thumb.png" width="244" height="165" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Comodo no?&lt;/p&gt;&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/gestione-schema-nhibernate/"&gt;Gestione dello schema database tramite NHibernate&lt;/a&gt; (12/13/2010)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/uno-usertype-generico-per-gli-enums/"&gt;Uno UserType generico per gli Enums&lt;/a&gt; (9/11/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/testare-il-mapping-di-nhibernate/"&gt;Testare il mapping di NHibernate&lt;/a&gt; (9/9/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/fluentnhibernate-10-rtm/"&gt;FluentNHibernate 1.0 RTM&lt;/a&gt; (8/31/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/fluent-nh-10-in-rc/"&gt;Fluent NH 1.0 in RC.&lt;/a&gt; (8/22/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/gestione-dei-datetime-ed-i-vari-timezone"&gt;&lt;strong&gt;More related document (8)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=1b1MfTNMA2I:k1KZNzJuUS4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=1b1MfTNMA2I:k1KZNzJuUS4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=1b1MfTNMA2I:k1KZNzJuUS4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=1b1MfTNMA2I:k1KZNzJuUS4:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=1b1MfTNMA2I:k1KZNzJuUS4:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=1b1MfTNMA2I:k1KZNzJuUS4:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=1b1MfTNMA2I:k1KZNzJuUS4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=1b1MfTNMA2I:k1KZNzJuUS4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=1b1MfTNMA2I:k1KZNzJuUS4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=1b1MfTNMA2I:k1KZNzJuUS4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=1b1MfTNMA2I:k1KZNzJuUS4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=1b1MfTNMA2I:k1KZNzJuUS4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=1b1MfTNMA2I:k1KZNzJuUS4:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><link>http://imperugo.tostring.it/blog/post/gestione-dei-datetime-ed-i-vari-timezone/</link><author>imperugo</author><comments>http://imperugo.tostring.it/blog/post/gestione-dei-datetime-ed-i-vari-timezone/#feedback</comments><guid isPermaLink="true">http://imperugo.tostring.it/blog/post/gestione-dei-datetime-ed-i-vari-timezone/</guid><pubDate>Mon, 16 May 2011 15:50:00 GMT</pubDate><category>Nhibernate</category><category>Database</category><category>TimeZone</category></item><item><title>ConfORM, NHibernate, Oracle e gli Integration Test</title><description>&lt;p&gt;In questi giorni sto lavorando parecchio ad un’applicazione che usa Oracle come repository e &lt;a title="Posts su NHibernate" href="http://www.tostring.it/categories/archive/nhibernate/"&gt;NHibernate&lt;/a&gt; come framework di persistenza. Essendo questa un’applicazione “delicata” ho necessità di creare una serie di integration test che mi “garantiscano” il corretto funzionamento, in modo da non avere spiacevoli sorprese in fase post deploy.&lt;/p&gt;  &lt;p&gt;Letta così la questione non presenta particolari criticità, ma ho dovuto affrontare un nuovo scenario riguardante Oracle e la sua gestione degli indici.&lt;/p&gt;  &lt;p&gt;Prima di entrare nel dettaglio tecnico vorrei puntualizzare che la soluzione da me adottata è la conseguenza di una totale inesperienza relativamente al mondo Oracle, potrebbe quindi esistere una strada migliore e più corretta per arrivare alla soluzione (magari se la conoscete, datemi qualche consiglio &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-openmouthedsmile" alt="Open-mouthed smile" src="http://www.tostring.it/UserFiles/imperugo/wlEmoticon-openmouthedsmile_2_1.png" /&gt;).&lt;/p&gt;  &lt;p&gt;Fatta tale premessa provo a descrivere un po’ lo scenario. Nella mia installazione interna all’azienda ho un solo database engine di Oracle che contiene al suo interno l’applicazione di sviluppo, quella di test ed infine quella di quality assurance. Quindi, lato database, ho tre schema/utenti ben differenti denominati rispettivamente &lt;strong&gt;Dev&lt;/strong&gt;, &lt;strong&gt;Test&lt;/strong&gt; e &lt;strong&gt;QA&lt;/strong&gt;, ed ognuno di questi ha le proprie tabelle con i propri dati, come mostrato dalla tabella seguente:&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="400"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="133"&gt;         &lt;p align="center"&gt;&lt;strong&gt;dev&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="133"&gt;         &lt;p align="center"&gt;&lt;strong&gt;test&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="133"&gt;         &lt;p align="center"&gt;&lt;strong&gt;QA&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;         &lt;p align="center"&gt;&lt;em&gt;&lt;font color="#666666" size="2"&gt;dev.users&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="133"&gt;         &lt;p align="center"&gt;&lt;em&gt;&lt;font color="#666666" size="2"&gt;test.users&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="133"&gt;         &lt;p align="center"&gt;&lt;em&gt;&lt;font color="#666666" size="2"&gt;qa.users&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;         &lt;p align="center"&gt;&lt;em&gt;&lt;font color="#666666" size="2"&gt;dev.roles&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="133"&gt;         &lt;p align="center"&gt;&lt;em&gt;&lt;font color="#666666" size="2"&gt;test.roles&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="133"&gt;         &lt;p align="center"&gt;&lt;em&gt;&lt;font color="#666666" size="2"&gt;qa.roles&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;         &lt;p align="center"&gt;&lt;em&gt;&lt;font color="#666666" size="2"&gt;dev.usersinroles&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="133"&gt;         &lt;p align="center"&gt;&lt;em&gt;&lt;font color="#666666" size="2"&gt;test.usersinroles&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="133"&gt;         &lt;p align="center"&gt;&lt;em&gt;&lt;font color="#666666" size="2"&gt;qa.usersinroles&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;   &lt;br /&gt;Essendo l’applicazione in uno stato di sviluppo più o meno avanzato, il database delle linea &lt;i&gt;dev&lt;/i&gt; non subisce molti “restyling”, al contrario del database dei test che viene cancellato e ricreato ad ogni test.&lt;/p&gt;  &lt;p&gt;Il mio problema è nato proprio durante la fase di “drop &amp;amp; create” dello schema: questo viene creato correttamente, ma poi la procedura di NHibernate non completa correttamente il tutto perché, al contrario di quanto avviene per le tabelle, gli indici non sono legati ad uno specifico schema, sollevandomi una brutta eccezione del tipo “nome oggetto già utilizzato” (riferendosi all’indice che si stava cercando di creare).    &lt;br /&gt;Se si riosserva la tabella riportata in precedenza si può facilmente intuire che l’univocità del nome della tabella è data dalla combinazione dello schema con il nome della tabella stessa. Purtroppo o per fortuna (direi più per fortuna) questa “combo” non esiste per gli indici, il che si traduce nel dover creare indici con nomi differenti per ogni “environment” in quanto trasversali all’interno del database engine.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;L’indice IX_ItemType non è dev.IX_ItemType!&lt;/strong&gt;     &lt;br /&gt;    &lt;br /&gt;La mia configurazione di NHibernate creava automaticamente degli indici per alcuni scenari (nello specifico per il “Table Per Class Hierarchy”) in modo da aiutare il database nell’eseguire le query. Con il supporto del buon &lt;a title="Fabio Maulo&amp;#39;s blog" href="http://fabiomaulo.blogspot.com" rel="nofollow" target="_blank"&gt;Fabio&lt;/a&gt; ho creato un Applier per &lt;a title="ConfORM" href="http://tostring.it/tags/archive/conform" target="_blank"&gt;ConfORM&lt;/a&gt; (in realtà ho fatto copia ed incolla di quello esistente) che mi permette di stabilire un prefisso per tutti gli indici, in modo da avere un risultato tipo il seguente: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;IX_MyIndex; &lt;/li&gt;    &lt;li&gt;IX_Test_MyIndex; &lt;/li&gt;    &lt;li&gt;IX_QA_MyIndex; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Una volta creato l’applier mi è bastato effettuare una merge dello stesso e, come per magia, tutti i test sono diventati verdi.    &lt;br /&gt;Per chi fosse interessato posto il codice dell’applier di ConfORM&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;public class DiscriminatorIndexNameApplier : IPatternApplier&amp;lt;Type, IClassAttributesMapper&amp;gt; {
    private readonly IDomainInspector domainInspector;
    readonly string indexPrefix;

    public DiscriminatorIndexNameApplier ( IDomainInspector domainInspector, string indexPrefix ) {
        this.domainInspector = domainInspector;
        this.indexPrefix = indexPrefix;
    }

    #region IPatternApplier&amp;lt;Type,IClassAttributesMapper&amp;gt; Members

    public bool Match ( Type subject ) {
        return domainInspector.IsTablePerClassHierarchy ( subject );
    }

    public void Apply ( Type subject, IClassAttributesMapper applyTo ) {
        applyTo.Discriminator ( dm =&amp;gt; dm.Column ( cm =&amp;gt; cm.Index ( indexPrefix + subject.Name + &amp;quot;EntityType&amp;quot; ) ) );
    }

    #endregion
}&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;e per il suo utilizzo:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;IPatternsAppliersHolder patternsAppliers = ( new ImperugoPatternsAppliersHolder ( orm , NHConfiguration.Instance.IndexPrefix ) )
    .Merge ( new ConfORM.DiscriminatorValueAsEnumValuePack &amp;lt;Person, PersonDiscriminatorMap&amp;gt; ( orm ) )
    .Merge ( new ConfORM.DiscriminatorValueAsEnumValuePack &amp;lt;View , ViewDiscriminatorMap&amp;gt; ( orm ))
    .Merge ( new ConfORM.DiscriminatorIndexNameApplier ( orm, NHConfiguration.Instance.IndexPrefix ) );&lt;/pre&gt;

&lt;br /&gt;&lt;font face="Calibri"&gt;dove l’ultima riga cambia la naming convention degli indici leggendo il prefisso dal file di configurazione.&lt;/font&gt; &lt;font face="Calibri"&gt;Enjoy!&lt;/font&gt;&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/gestione-schema-nhibernate/"&gt;Gestione dello schema database tramite NHibernate&lt;/a&gt; (12/13/2010)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/uno-usertype-generico-per-gli-enums/"&gt;Uno UserType generico per gli Enums&lt;/a&gt; (9/11/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/testare-il-mapping-di-nhibernate/"&gt;Testare il mapping di NHibernate&lt;/a&gt; (9/9/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/fluentnhibernate-10-rtm/"&gt;FluentNHibernate 1.0 RTM&lt;/a&gt; (8/31/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/fluent-nh-10-in-rc/"&gt;Fluent NH 1.0 in RC.&lt;/a&gt; (8/22/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/conform-nhibernate-oracle-e-gli-integration-test"&gt;&lt;strong&gt;More related document (8)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=OolYrNtGXdQ:7V8ls3QBbxQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=OolYrNtGXdQ:7V8ls3QBbxQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=OolYrNtGXdQ:7V8ls3QBbxQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=OolYrNtGXdQ:7V8ls3QBbxQ:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=OolYrNtGXdQ:7V8ls3QBbxQ:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=OolYrNtGXdQ:7V8ls3QBbxQ:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=OolYrNtGXdQ:7V8ls3QBbxQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=OolYrNtGXdQ:7V8ls3QBbxQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=OolYrNtGXdQ:7V8ls3QBbxQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=OolYrNtGXdQ:7V8ls3QBbxQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=OolYrNtGXdQ:7V8ls3QBbxQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=OolYrNtGXdQ:7V8ls3QBbxQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=OolYrNtGXdQ:7V8ls3QBbxQ:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><link>http://imperugo.tostring.it/blog/post/conform-nhibernate-oracle-e-gli-integration-test/</link><author>imperugo</author><comments>http://imperugo.tostring.it/blog/post/conform-nhibernate-oracle-e-gli-integration-test/#feedback</comments><guid isPermaLink="true">http://imperugo.tostring.it/blog/post/conform-nhibernate-oracle-e-gli-integration-test/</guid><pubDate>Wed, 20 Apr 2011 15:45:00 GMT</pubDate><category>Nhibernate</category><category>Oracle</category><category>ConfORM</category></item><item><title>Gestione dello schema database tramite NHibernate</title><description>&lt;p&gt;Dopo mesi di assenza, finalmente trovo di nuovo il tempo di “bloggare”, e la mia intenzione, questa volta, è di parlare di &lt;a title="Posts su NHibernate" href="http://www.tostring.it/categories/archive/nhibernate/"&gt;NHibernate&lt;/a&gt; (fresco di GA), di cui sto facendo un uso abbastanza “spinto” in un progetto.     &lt;br /&gt;Nello specifico ho avuto l’esigenza di dover gestire con NHibernate la creazione del database - e fin qui nulla di speciale - ma con l’obbligo di creare anche delle funzioni SQL per i vari databases supportati.&lt;/p&gt;  &lt;p&gt;Uno dei principali requirements dell’applicazione è il supporto a ben &lt;strong&gt;tre versioni differenti di Sql Server&lt;/strong&gt; più &lt;strong&gt;due di Oracle&lt;/strong&gt;; per come sono strutturati il dominio ed il database, per poter effettuare determinate queries ho dovuto far uso di alcune funzioni lato database, in quanto non riproducibili tramite Object Query Language.&lt;/p&gt;  &lt;p&gt;Fortunatamente NHibernate permette di utilizzare delle funzioni SQL Custom all’interno delle proprie queries sia se si fa uso di HQL, sia di Criteria API che di Linq.    &lt;br /&gt;Il loro utilizzo è veramente semplice; per prima cosa è necessario creare un proprio dialect, che erediti da quello più adatto al nostro database, e registrare le funzioni all’interno del suo costruttore, come mostrato dal codice seguente:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;internal class SqlServer2008Dialect : MsSql2008Dialect {
    
    /// &amp;lt;summary&amp;gt;
    /// Initializes a new instance of the &amp;lt;see cref=&amp;quot;SqlServer2008Dialect&amp;quot;/&amp;gt; class.
    /// &amp;lt;/summary&amp;gt;
    public SqlServer2008Dialect ( ) {

        string monthFunction = string.Format(&amp;quot;{0}.IsMonth&amp;quot;, NHConfiguration.Instance.DatabaseSchema);
        string yearFunction = string.Format(&amp;quot;{0}.IsYear&amp;quot;, NHConfiguration.Instance.DatabaseSchema);

        base.RegisterFunction ( &amp;quot;IsMonth&amp;quot; , new StandardSQLFunction ( monthFunction , NHibernateUtil.Int32 ) );
        base.RegisterFunction ( &amp;quot;IsYear&amp;quot; , new StandardSQLFunction ( yearFunction , NHibernateUtil.Int32 ) );
    }
}&lt;/pre&gt;

&lt;p&gt;A questo punto possiamo utilizzare la funzione all’interno delle nostre query in maniera molto semplice:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;Session.CreateQuery ( &amp;quot;from Article p where IsMonth( p.PublishDate ) = :month and IsYear( p.PublishDate ) = :year&amp;quot; )
    .SetParameter(&amp;quot;month&amp;quot;,month)
    .SetParameter(&amp;quot;year&amp;quot;, year)
    .SetFirstResult(pageIndex * pageSize)
    .SetFirstResult(pageIndex * pageSize)
    .SetMaxResults(pageSize)
    .SetReadOnly(!enableTracking)
    .List&amp;lt;Article&amp;gt;();&lt;/pre&gt;

&lt;p&gt;Come già detto in apertura, una delle caratteristiche dell’applicazione è la creazione ed aggiornamento del database tramite Nhibernate, il che si traduce nell’aggiungere gli scripts di creazione delle funzioni SQL lato codice; tuttavia, essendo lo schema del database impostato lato configurazione, è necessario manipolare gli scripts prima che questi siano “dati in pasto” a NHibernate per la creazione dello schema.&lt;/p&gt;

&lt;p&gt;Gli steps da seguire sono pochi e piuttosto semplici, a dimostrazione dell’ottima struttura e flessibilità offerta da NHibernate. Per prima cosa è necessario preparare gli scripts di creazione e cancellazione delle funzioni SQL, tipo la seguente:&lt;/p&gt;

&lt;pre class="brush: sql;"&gt;--SCRIPT DI CREAZIONE

CREATE FUNCTION [IsMonth]
       (
@date datetime
       )
       RETURNS int

       WITH EXECUTE AS CALLER
AS
BEGIN
  IF @date IS NULL RETURN 0
    RETURN Datepart(mm,@date)
END

GO

CREATE FUNCTION [IsYear]
(
  @date datetime
)
RETURNS int

WITH EXECUTE AS CALLER
  AS
  BEGIN
    IF @date IS NULL RETURN 0
      RETURN Datepart(yy,@date)
  END

GO

--SCRIPT DI CANCELLAZIONE

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[IsMonth]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
    DROP FUNCTION [IsMonth]
GO

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[IsYear]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
    DROP FUNCTION [IsYear]
GO&lt;/pre&gt;

&lt;p&gt;È importante rimuovere gli schema del database tipo “dbo” dallo script, in modo da poter aggiungere lo schema desiderato a runtime.&lt;/p&gt;

&lt;p&gt;A questo punto va preparato un file XML di mapping che conterrà questi scripts, come mostrato di seguito:&lt;/p&gt;

&lt;pre class="brush: xml;"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;
&amp;lt;hibernate-mapping xmlns=&amp;quot;urn:nhibernate-mapping-2.2&amp;quot;&amp;gt;
    &amp;lt;database-object&amp;gt;
        &amp;lt;create&amp;gt;
      &amp;lt;!-- Inserire qui gli script di creazione --&amp;gt;
        &amp;lt;/create&amp;gt;
        &amp;lt;drop&amp;gt;
      &amp;lt;!-- Inserire qui gli script di cancellazione --&amp;gt;
        &amp;lt;/drop&amp;gt;
    &amp;lt;/database-object&amp;gt;
&amp;lt;/hibernate-mapping&amp;gt;&lt;/pre&gt;

&lt;p&gt;Da qui in poi è sufficiente eseguire una Regular Expression per poter aggiungere lo schema proveniente dal nostro file di configurazione e, solo a questo punto, è possibile passare a NHibernate il codice di XML contenente gli scripts di creazione e cancellazione delle funzioni.&lt;/p&gt;

&lt;pre class="brush: xml;"&gt;db.Dialect&amp;lt;SqlServer2008Dialect&amp;gt;();
db.Driver&amp;lt;SqlClientDriver&amp;gt;();
databaseObjects = Resources.DatabaseObjects.MsSQL2008;

if (databaseObjects != null)
    databaseObjects = Regex.Replace(databaseObjects, @&amp;quot;(\[.*\])&amp;quot;, string.Format(&amp;quot;[{0}].$1&amp;quot;, dbSchema));

if (!string.IsNullOrEmpty(databaseObjects)){
    //configuration è la configuration di NHibernate
    configuration.AddXmlString ( databaseObjects);
}&lt;/pre&gt;

&lt;p&gt;Anche in scenari in cui non si abbia l’esigenza di dover supportare diverse tipologie di database, consiglio sempre, quando possibile, di lasciare l’onere della creazionde del database all’ORM, in modo da poter creare e cancellare lo schema del database durante l’esecuzione dei nostri integration tests con molta semplicitià.&lt;/p&gt;

&lt;p&gt;Ciauz &lt;/p&gt;&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/conform-nhibernate-oracle-e-gli-integration-test/"&gt;ConfORM, NHibernate, Oracle e gli Integration Test&lt;/a&gt; (4/20/2011)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/gestione-dei-datetime-ed-i-vari-timezone/"&gt;Gestione dei DateTime ed i vari TimeZone&lt;/a&gt; (5/16/2011)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/nhibernate-21-in-rtm/"&gt;NHibernate 2.1 in RTM&lt;/a&gt; (7/20/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/problema-con-nhibernate-e-table-for-hierarchy/"&gt;Problema con NHibernate e Table for Hierarchy&lt;/a&gt; (5/18/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/riflessioni-su-nhibernate/"&gt;Riflessioni su NHibernate&lt;/a&gt; (7/17/2006)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/Gestione-Schema-NHibernate"&gt;&lt;strong&gt;More related document (14)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=V7nPMYfIkTU:3AcYZ4j09ok:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=V7nPMYfIkTU:3AcYZ4j09ok:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=V7nPMYfIkTU:3AcYZ4j09ok:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=V7nPMYfIkTU:3AcYZ4j09ok:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=V7nPMYfIkTU:3AcYZ4j09ok:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=V7nPMYfIkTU:3AcYZ4j09ok:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=V7nPMYfIkTU:3AcYZ4j09ok:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=V7nPMYfIkTU:3AcYZ4j09ok:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=V7nPMYfIkTU:3AcYZ4j09ok:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=V7nPMYfIkTU:3AcYZ4j09ok:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=V7nPMYfIkTU:3AcYZ4j09ok:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=V7nPMYfIkTU:3AcYZ4j09ok:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=V7nPMYfIkTU:3AcYZ4j09ok:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><link>http://imperugo.tostring.it/blog/post/gestione-schema-nhibernate/</link><author>imperugo</author><comments>http://imperugo.tostring.it/blog/post/gestione-schema-nhibernate/#feedback</comments><guid isPermaLink="true">http://imperugo.tostring.it/blog/post/gestione-schema-nhibernate/</guid><pubDate>Mon, 13 Dec 2010 16:45:00 GMT</pubDate><category>Nhibernate</category><category>Sql</category><category>Oracle</category><category>ORM</category><category>Database</category></item><item><title>Introduzione a ConfORM</title><description>&lt;p&gt;Chi mi segue su &lt;a title="My Twitter Page" href="http://twitter.com/imperugo" rel="nofollow" target="_blank"&gt;Twitter&lt;/a&gt; sicuramente saprà che ultimamente mi sono messo a “giocare” un po’ con &lt;strong&gt;&lt;a title="ConfORM Project page" href="http://code.google.com/p/codeconform/" rel="nofollow" target="_blank"&gt;ConfORM&lt;/a&gt;&lt;/strong&gt;, e, nello specifico, ho deciso di rimpiazzare FluentNHibernate in &lt;a title="Dexter Blog Engine Category" href="http://www.imperugo.tostring.it/categories/archive/Dexter" target="_blank"&gt;Dexter&lt;/a&gt;, per far strada al Framework prodotto da &lt;a title="Fabio Maulo&amp;#39;s blog" href="http://fabiomaulo.blogspot.com/" rel="nofollow" target="_blank"&gt;Fabio Maulo&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Per chi non lo conoscesse, ConfORM è un Framework che facilità incredibilmente tutta la parte di mapping del nostro dominio - quando si utilizza NHibernate per la persistenza - cambiando totalmente l’approccio; ma andiamo per gradi.&lt;/p&gt;  &lt;p&gt;Oggigiorno esistono diversi modi di scrivere il mapping per &lt;a title="NHibernate posts" href="http://www.tostring.it/categories/archive/nhibernate/" target="_blank"&gt;NHibernate&lt;/a&gt;, partendo dal classico e mai datato XML, fino ad arrivare a Framework più recenti come FluntNHibernate, Ddl2Hbm, VisualNHibernate, etc.     &lt;br /&gt;Purtroppo questi framework hanno lo stesso approccio, obbligandoci a specificare la corrispondenza di ogni singola property di ciascuna classe di dominio verso il database.&lt;/p&gt;  &lt;p&gt;Non conosco i vostri gusti relativamente alla scrittura di codice, ma personalmente ritengo molto noiosa e ripetitiva la fase di stesura del mapping, motivo per cui ConfORM la vince su tutti gli altri.&lt;/p&gt;  &lt;h4&gt;&lt;b&gt;L’approccio di ConfORM.&lt;/b&gt;&lt;/h4&gt;  &lt;p&gt;Come già accennato ConfORM ha preso totalmente un’altra strada; di fatto inizialmente può lasciare l’utente un po’ spiazzato, ma quando si è capito il funzionamento è sicuramente un viaggio di sola andata, in quanto induce ad abbandonare totalmente il mapping “tradizionale”.    &lt;br /&gt;Di fatto quello che è necessario fare è “istruire” ConfORM con le nostre “regole” di sviluppo e di nomenclatura e specificare solo le eventuali eccezioni, lasciando a lui il compito di generare e gestire tutta la fase di mapping.&lt;/p&gt;  &lt;p&gt;Per capire meglio il vantaggio, il grafico seguente mostra il Dominio di Dexter che in precedenza era mappato con FluentNHibernate in 27 classi differenti ed ora è mappato in poco più di 20 righe di mapping &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://tostring.it/UserFiles/imperugo/ClassDiagram1_2.png" rel="shadowbox[ConfORM1]"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ClassDiagram1" border="0" alt="ClassDiagram1" src="http://tostring.it/UserFiles/imperugo/ClassDiagram1_thumb.png" width="474" height="374" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;&lt;font style="font-weight: bold"&gt;Maggior Produttività e controllo.&lt;/font&gt;     &lt;br /&gt;&lt;/h4&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;Un altro vantaggio sicuramente interessante è l’aumento di produttività: possiamo aggiungere e togliere classi al nostro dominio senza toccare il mapping, a condizione che queste rispettino le regole stabilite precedentemente.     &lt;br /&gt;Quest’aspetto è sicuramente molto interessante perché ci permette di modificare il dominio senza preoccuparci di dover aggiornare il mapping, e riduce il rischio di introdurre errori dovuti ai continui cambiamenti.     &lt;br /&gt;Un altro aspetto che adoro è la rigidità che si può introdurre nel lavoro in team, in quanto se qualche sviluppatore non rispetta le regole di mapping prestabilite è obbligato ad andare a dichiarare l’eccezione manualmente e quindi il cambiamento è facilmente identificabile; un esempio banale potrebbe essere la nomenclatura delle tabelle: si è stabilito che sul database esse debbano chiamarsi con il nome della classe di dominio ma al plurare e, se un dev vuol chiamare la tabella in maniera differente è obbligato a gestire lo special case a mano e specificarlo nel mapping.&lt;/p&gt;  &lt;h4&gt;&lt;b&gt;Performance:&lt;/b&gt;&lt;/h4&gt;  &lt;p&gt;L’utilizzo di ConfORM porta anche vantaggi prestazionali alla nostra applicazione in quanto, a differenza di tutti gli altri Framework di mapping, genera direttamente le classi necessarie a NHibernate per il suo utilizzo, saltando così tutta la fase di parsing del file xml contenente il mapping.    &lt;br /&gt;Ovviamente quest’aumento di performance è beneficiabile solo in fase di startup ed è sicuramente apprezzabile quando si ha a che fare con domini piuttosto corposi.     &lt;br /&gt;Per capire meglio il funzionamento di ConfORM rispetto al classico mapping o ad altri Framework, riporto qui un grafico “rubato” dal blog di Fabio che spiega perfettamente il perché dell’aumento di performances.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://tostring.it/UserFiles/imperugo/confORM_2.png" rel="shadowbox[ConfORM1]"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="confORM" border="0" alt="confORM" src="http://tostring.it/UserFiles/imperugo/confORM_thumb.png" width="474" height="445" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/h4&gt;  &lt;h4&gt;&lt;strong&gt;Conclusioni&lt;/strong&gt;:&lt;/h4&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;Ovviamente seguiranno altri post che mostreranno la parte più tecnica di ConfORM, ma per chi non volesse aspettare riporto alcuni link utili:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Download di ConfORM – &lt;a title="Download ConfORM" href="http://code.google.com/p/codeconform/" rel="nofollow" target="_blank"&gt;Download&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;Una serie di post su ConfORM è disponibile &lt;a title="ConfORM Posts" href="http://fabiomaulo.blogspot.com/search/label/ConfORM" rel="nofollow" target="_blank"&gt;qui&lt;/a&gt;. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Enjoy your mapping.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=aWrglZSJjww:SO_4T9zjFM8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=aWrglZSJjww:SO_4T9zjFM8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=aWrglZSJjww:SO_4T9zjFM8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=aWrglZSJjww:SO_4T9zjFM8:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=aWrglZSJjww:SO_4T9zjFM8:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=aWrglZSJjww:SO_4T9zjFM8:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=aWrglZSJjww:SO_4T9zjFM8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=aWrglZSJjww:SO_4T9zjFM8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=aWrglZSJjww:SO_4T9zjFM8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=aWrglZSJjww:SO_4T9zjFM8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=aWrglZSJjww:SO_4T9zjFM8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=aWrglZSJjww:SO_4T9zjFM8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=aWrglZSJjww:SO_4T9zjFM8:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><link>http://imperugo.tostring.it/blog/post/introduzione-conform/</link><author>imperugo</author><comments>http://imperugo.tostring.it/blog/post/introduzione-conform/#feedback</comments><guid isPermaLink="true">http://imperugo.tostring.it/blog/post/introduzione-conform/</guid><pubDate>Mon, 20 Sep 2010 15:45:00 GMT</pubDate><category>Nhibernate</category><category>NHibernateFluent</category><category>Mapping</category><category>ConfORM</category></item><item><title>Uno UserType generico per gli Enums</title><description>&lt;p&gt;NHibernate tende a mappare gli &lt;em&gt;Enums&lt;/em&gt; come stringhe nel database; questo a volte pu&amp;ograve; non essere un problema, ma personalmente preferisco memorizzarli in un intero, o ancora meglio un &lt;em&gt;tynint&lt;/em&gt;, infatti con questo tipo di formato si ha un netto risparmio di spazio, ma anche un vantaggio per eventuali query.&lt;/p&gt;
&lt;p&gt;NHibernate permette di cambiare il modo di persistere un tipo di oggetto del nostro domain model sul database tramite delle apposite classi; tradotto pi&amp;ugrave; semplicemente permette di avere una classe sulla propria entity e un semplice campo nel database (ad esempio un intero o un varchar), come potrebbe essere il &lt;em&gt;CultureInfo&lt;/em&gt; che, in una classe come quella mostrata di seguito, &amp;egrave; un oggetto, mentre sul database una semplice string tipo &amp;ldquo;en-US&amp;rdquo;.&lt;/p&gt;
&lt;pre class="brush: csharp; ruler: true;"&gt;
public class Comment : EntityBase
{
    public virtual Item Item { get; set; }
    public virtual DateTime CommentDate { get; set; }
    public virtual string Message { get; set; }
    public virtual string Name { get; set; }
    public virtual string Email { get; set; }
    public virtual bool Notify { get; set; }
    public virtual string WebSite { get; set; }
    public virtual bool Approved { get; set; }
    public virtual bool IsSpam { get; set; }
    public virtual System.Globalization.CultureInfo Culture { get; set; }
}&lt;/pre&gt;
&lt;p&gt;Lo stesso approccio pu&amp;ograve; essere utilizzato per gli &lt;em&gt;Enums&lt;/em&gt;, quindi un &lt;em&gt;enum&lt;/em&gt; come il seguente:&lt;/p&gt;
&lt;pre class="brush: csharp; ruler: true;"&gt;
public enum BlogRollFriendType : short 
{
    Nothing = 0,
    Contact = 1,
    Friend = 2,
    Acquaintance = 3
}&lt;/pre&gt;
&lt;p&gt;pu&amp;ograve; essere persistito come un tinyint sul database grazie ad uno UserType come quello mostrato di seguito:&lt;/p&gt;
&lt;pre class="brush: csharp; ruler: true;"&gt;
public class GenericEnumMapper&amp;lt;T&amp;gt; : IUserType
{
    #region IUserType Members

    public new bool Equals(object x, object y)
    {
        if (ReferenceEquals(x, y)) return true;
        if (x == null || y == null) return false;
        return x.Equals(y);
    }

    public int GetHashCode(object x)
    {
        return x.GetHashCode();
    }

    public object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        object obj = NHibernateUtil.Int16.NullSafeGet(rs, names[0]);

        if (obj == null)
            return null;

        return (T) obj;
    }

    public void NullSafeSet(IDbCommand cmd, object value, int index)
    {
        if (value == null)
            ((IDataParameter) cmd.Parameters[index]).Value = DBNull.Value;
        else
            ((IDataParameter) cmd.Parameters[index]).Value = (short) value;
    }

    public object DeepCopy(object value)
    {
        return value;
    }

    public object Replace(object original, object target, object owner)
    {
        return original;
    }

    public object Assemble(object cached, object owner)
    {
        return cached;
    }

    public object Disassemble(object value)
    {
        return value;
    }

    public SqlType[] SqlTypes
    {
        get { return new[] {new SqlType(DbType.Int16)}; }
    }

    public Type ReturnedType
    {
        get { return typeof (T); }
    }

    public bool IsMutable
    {
        get { return false; }
    }

    #endregion
}&lt;/pre&gt;
&lt;p&gt;L&amp;rsquo;implementazione &amp;egrave; piuttosto semplice, l&amp;rsquo;unica accortezza che bisogna avere per poter persistere l&amp;rsquo;enum come tinyint &amp;egrave; specificare lo usertype nel mapping, come mostrato di seguito:&lt;/p&gt;
&lt;pre class="brush: csharp; ruler: true;"&gt;
public BlogRoll()
{
    Table(&amp;quot;BlogsRoll&amp;quot;);
    DynamicUpdate();
    LazyLoad();
    Cache.NonStrictReadWrite();

    Id(x =&amp;gt; x.ID)
        .GeneratedBy.Identity();

    Map(x =&amp;gt; x.Name)
        .Not.Nullable()
        .Length(100);

    Map(x =&amp;gt; x.Link)
        .Not.Nullable()
        .Length(100);

    Map(x =&amp;gt; x.IsMyBlog);
    Map(x =&amp;gt; x.FriendType)
        .CustomType(typeof(Dexter.NHibernate.Helpers.UserTypes.GenericEnumMapper&amp;lt;BlogRollFriendType&amp;gt;));

    Map(x =&amp;gt; x.GeographicalType)
        .CustomType(typeof (Dexter.NHibernate.Helpers.UserTypes.GenericEnumMapper&amp;lt;BlogRollGeographicalType&amp;gt;));
}&lt;/pre&gt;
&lt;p&gt;Lo screenshot seguente mostra la struttura della tabella:   &lt;br /&gt;
&lt;a href="http://imperugo.tostring.it/Content/Uploaded/image/table._2.gif" rel="shadowbox[Uno-UserType-generico-per-gli-Enums];options={counterType:'skip',continuous:true,animSequence:'sync'}"&gt;&lt;img SinglelineIgnoreCase singlelineignorecase="" style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="table." border="0" alt="table." width="294" height="339" src="http://imperugo.tostring.it/Content/Uploaded/image/table._thumb.gif" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/fluent-nh-10-in-rc/"&gt;Fluent NH 1.0 in RC.&lt;/a&gt; (8/22/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/fluentnhibernate-10-rtm/"&gt;FluentNHibernate 1.0 RTM&lt;/a&gt; (8/31/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/testare-il-mapping-di-nhibernate/"&gt;Testare il mapping di NHibernate&lt;/a&gt; (9/9/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/linqtonhibernate-10-is-out/"&gt;LinqToNHibernate 1.0 is Out&lt;/a&gt; (7/26/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/nhibernate-21-in-rtm/"&gt;NHibernate 2.1 in RTM&lt;/a&gt; (7/20/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/Uno-UserType-generico-per-gli-Enums"&gt;&lt;strong&gt;More related document (8)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=XQsKdTk03Fc:xkJEkwDXQqk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=XQsKdTk03Fc:xkJEkwDXQqk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=XQsKdTk03Fc:xkJEkwDXQqk:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=XQsKdTk03Fc:xkJEkwDXQqk:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=XQsKdTk03Fc:xkJEkwDXQqk:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=XQsKdTk03Fc:xkJEkwDXQqk:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=XQsKdTk03Fc:xkJEkwDXQqk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=XQsKdTk03Fc:xkJEkwDXQqk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=XQsKdTk03Fc:xkJEkwDXQqk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=XQsKdTk03Fc:xkJEkwDXQqk:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=XQsKdTk03Fc:xkJEkwDXQqk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=XQsKdTk03Fc:xkJEkwDXQqk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=XQsKdTk03Fc:xkJEkwDXQqk:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><link>http://imperugo.tostring.it/blog/post/uno-usertype-generico-per-gli-enums/</link><author>imperugo</author><comments>http://imperugo.tostring.it/blog/post/uno-usertype-generico-per-gli-enums/#feedback</comments><guid isPermaLink="true">http://imperugo.tostring.it/blog/post/uno-usertype-generico-per-gli-enums/</guid><pubDate>Fri, 11 Sep 2009 21:30:32 GMT</pubDate><category>Mapping</category><category>Nhibernate</category><category>NHibernateFluent</category></item><item><title>Testare il mapping di NHibernate</title><description>&lt;p&gt;Un buon mapping &amp;egrave; la base di un buon risultato ottenibile tramite l&amp;rsquo;uso di un O/RM.    &lt;br /&gt;
Anche se in molti esempi pu&amp;ograve; sembrare semplice effettuare il mapping, in applicazioni reali (o con particolari richieste) questo pu&amp;ograve; essere tutt&amp;rsquo;altro che semplice.     &lt;br /&gt;
In &lt;a title="Dexter Blog Engine" target="_blank" href="http://imperugo.tostring.it/About/Dexter"&gt;Dexter&lt;/a&gt; ho avuto la necessit&amp;agrave; di realizzare diversi UserType per gestire enumerati, timezone, conversioni, ecc, ed ovviamente, essendoci una logica di calcolo dietro, questi andrebbero testati per evitare di avere un&amp;rsquo;incongruenza di dati o, nel peggiore dei casi, degli errori.     &lt;br /&gt;
&lt;a title="FluentNHibernate" rel="nofollow" target="_blank" href="http://fluentnhibernate.org/"&gt;FluentNHibernate&lt;/a&gt; mette a disposizione delle classi che permettono di effettuare lo UnitTest del mapping verificando cos&amp;igrave; che la CRUD della entity funzioni a dovere; quindi, nello specifico, si ha a disposizione un mini Framework per testare le seguenti operazioni:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Inserimento della entity;&lt;/li&gt;
    &lt;li&gt;Modifica della entity;&lt;/li&gt;
    &lt;li&gt;Recupero della entity;&lt;/li&gt;
    &lt;li&gt;Cancellazione della entity;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lo snippet seguente mostra come effettuare questo tipo di test con poche righe di codice, avendo la certezza che il mapping sia corretto:&lt;/p&gt;
&lt;pre class="brush: csharp; ruler: true;"&gt;
[TestMethod]
public void BlogRollMap()
{
    new PersistenceSpecification&amp;lt;BlogRoll&amp;gt;(session)
        .CheckProperty(c =&amp;gt; c.ID, 1)
        .CheckProperty(c =&amp;gt; c.Co_worker, true)
        .CheckProperty(c =&amp;gt; c.Colleague, true)
        .CheckProperty(c =&amp;gt; c.Crush, true)
        .CheckProperty(c =&amp;gt; c.Date, true)
        .CheckProperty(c =&amp;gt; c.FamilyType, BlogRollFamilyType.Sibling)
        .CheckProperty(c =&amp;gt; c.FriendType, BlogRollFriendType.Contact)
        .CheckProperty(c =&amp;gt; c.GeographicalType, BlogRollGeographicalType.Neighbor)
        .CheckProperty(c =&amp;gt; c.IsMyBlog, true)
        .CheckProperty(c =&amp;gt; c.Link, &amp;quot;http://www.microsoft.com&amp;quot;)
        .CheckProperty(c =&amp;gt; c.Met, true)
        .CheckProperty(c =&amp;gt; c.Muse, true)
        .CheckProperty(c =&amp;gt; c.Name, &amp;quot;Microsoft&amp;quot;)
        .CheckProperty(c =&amp;gt; c.Position, 1)
        .CheckProperty(c =&amp;gt; c.Sweetheart, true)
        .CheckProperty(c =&amp;gt; c.Username, &amp;quot;imperugo&amp;quot;)
        .VerifyTheMappings();
}&lt;/pre&gt;
&lt;p&gt;Inoltre per condizioni particolari &amp;egrave; possibile specificare, tramite l&amp;rsquo;apposito overload del costruttore, una classe IEqualityComparer per effettuare una comparazione custom dei dati, come mostrato di seguito:&lt;/p&gt;
&lt;pre class="brush: csharp; ruler: true;"&gt;
public class SiteConfigurationEqualityComparer : IEqualityComparer
{
    public new bool Equals(object x, object y)
    {
        if (x == null || y == null)
            return false;

        if (x is TimeZoneInfo &amp;amp;&amp;amp; y is TimeZoneInfo)
            return ((TimeZoneInfo)x).Id == ((TimeZoneInfo)y).Id;

        if (x is ReCaptcha &amp;amp;&amp;amp; y is ReCaptcha)
        {
            var r1 = (ReCaptcha)x;
            var r2 = (ReCaptcha)y;

            return (r1.Enable == r2.Enable &amp;amp;&amp;amp;
                    r1.PrivateKey == r2.PrivateKey &amp;amp;&amp;amp;
                    r1.PublicKey == r2.PublicKey &amp;amp;&amp;amp;
                    r1.Theme == r2.Theme);
        }
}&lt;/pre&gt;
&lt;p&gt;Maggiori info sono disponibili &lt;a title="FluentMapping Persistance Service" rel="nofollow" target="_blank" href="http://wiki.fluentnhibernate.org/Persistence_specification_testing"&gt;qui&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ciauz&lt;/p&gt;&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/uno-usertype-generico-per-gli-enums/"&gt;Uno UserType generico per gli Enums&lt;/a&gt; (9/11/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/fluentnhibernate-10-rtm/"&gt;FluentNHibernate 1.0 RTM&lt;/a&gt; (8/31/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/fluent-nh-10-in-rc/"&gt;Fluent NH 1.0 in RC.&lt;/a&gt; (8/22/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/generazione-di-dati-fake-durante-la-scrittura-di-test/"&gt;Generazione di dati fake durante la scrittura di test.&lt;/a&gt; (9/15/2010)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/utilizzare-un-ramdisk-per-l-and-rsquo-esecuzione-dei-test/"&gt;Utilizzare un RamDisk per l’esecuzione dei Test&lt;/a&gt; (10/13/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/Testare-il-mapping-di-NHibernate"&gt;&lt;strong&gt;More related document (13)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=MO00ap90k48:LI_ReDq3wa4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=MO00ap90k48:LI_ReDq3wa4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=MO00ap90k48:LI_ReDq3wa4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=MO00ap90k48:LI_ReDq3wa4:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=MO00ap90k48:LI_ReDq3wa4:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=MO00ap90k48:LI_ReDq3wa4:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=MO00ap90k48:LI_ReDq3wa4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=MO00ap90k48:LI_ReDq3wa4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=MO00ap90k48:LI_ReDq3wa4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=MO00ap90k48:LI_ReDq3wa4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=MO00ap90k48:LI_ReDq3wa4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=MO00ap90k48:LI_ReDq3wa4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=MO00ap90k48:LI_ReDq3wa4:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><link>http://imperugo.tostring.it/blog/post/testare-il-mapping-di-nhibernate/</link><author>imperugo</author><comments>http://imperugo.tostring.it/blog/post/testare-il-mapping-di-nhibernate/#feedback</comments><guid isPermaLink="true">http://imperugo.tostring.it/blog/post/testare-il-mapping-di-nhibernate/</guid><pubDate>Wed, 09 Sep 2009 08:49:05 GMT</pubDate><category>Mapping</category><category>Nhibernate</category><category>Testing</category></item><item><title>FluentNHibernate 1.0 RTM</title><description>&lt;p&gt;
	Era gi&amp;agrave; nell&amp;rsquo;aria (maggiori info &lt;a href="http://imperugo.tostring.it/Blog/Post/Fluent-NH-10-in-RC" target="_blank" title="Fluent NH 10 in RC"&gt;qui&lt;/a&gt;), ed infatti &amp;egrave; disponibile la versione RTM di &lt;a href="http://fluentnhibernate.org/" rel="nofollow" target="_blank" title="FluentNHibernate"&gt;FluentNHibernate&lt;/a&gt; 1.0 come annunciato dal blog di NHibernate &lt;a href="http://nhforge.org/blogs/nhibernate/archive/2009/08/29/fluent-nhibernate-1-0.aspx" rel="nofollow" target="_blank" title="Fluent NHibernate 1.0 RTM Out"&gt;qui&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
	Tutti i changeset del FluentMapping, AutoMapping e Conventions le trovate &lt;a href="http://wiki.fluentnhibernate.org/Release_notes_1.0" rel="nofollow" target="_blank" title="FluentNhibernate 1.0 RTM Changeset"&gt;qui&lt;/a&gt;, mentre a questo &lt;a href="http://fluentnhibernate.org/downloads" rel="nofollow" target="_blank" title="FluentNHibernate 1.0 RTM"&gt;indirizzo&lt;/a&gt; trovate il download.&lt;/p&gt;
&lt;p&gt;
	Buon Mapping :)&lt;/p&gt;
&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/uno-usertype-generico-per-gli-enums/"&gt;Uno UserType generico per gli Enums&lt;/a&gt; (9/11/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/fluent-nh-10-in-rc/"&gt;Fluent NH 1.0 in RC.&lt;/a&gt; (8/22/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/testare-il-mapping-di-nhibernate/"&gt;Testare il mapping di NHibernate&lt;/a&gt; (9/9/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/linqtonhibernate-10-is-out/"&gt;LinqToNHibernate 1.0 is Out&lt;/a&gt; (7/26/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/nhibernate-21-in-rtm/"&gt;NHibernate 2.1 in RTM&lt;/a&gt; (7/20/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/FluentNHibernate-10-RTM"&gt;&lt;strong&gt;More related document (20)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=QnwSMl_GKKQ:IHqLrnGsCkw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=QnwSMl_GKKQ:IHqLrnGsCkw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=QnwSMl_GKKQ:IHqLrnGsCkw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=QnwSMl_GKKQ:IHqLrnGsCkw:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=QnwSMl_GKKQ:IHqLrnGsCkw:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=QnwSMl_GKKQ:IHqLrnGsCkw:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=QnwSMl_GKKQ:IHqLrnGsCkw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=QnwSMl_GKKQ:IHqLrnGsCkw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=QnwSMl_GKKQ:IHqLrnGsCkw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=QnwSMl_GKKQ:IHqLrnGsCkw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=QnwSMl_GKKQ:IHqLrnGsCkw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=QnwSMl_GKKQ:IHqLrnGsCkw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=QnwSMl_GKKQ:IHqLrnGsCkw:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><link>http://imperugo.tostring.it/blog/post/fluentnhibernate-10-rtm/</link><author>imperugo</author><comments>http://imperugo.tostring.it/blog/post/fluentnhibernate-10-rtm/#feedback</comments><guid isPermaLink="true">http://imperugo.tostring.it/blog/post/fluentnhibernate-10-rtm/</guid><pubDate>Mon, 31 Aug 2009 09:36:37 GMT</pubDate><category>Mapping</category><category>News</category><category>Nhibernate</category><category>NHibernateFluent</category></item><item><title>Fluent NH 1.0 in RC.</title><description>&lt;p&gt;&lt;a href="http://fluentnhibernate.org/" target="_blank"&gt;NHibernateFluent&lt;/a&gt; &amp;egrave; una valida alternativa al metodo classico (XML Based) di mappare le entity con con NHibernate.     &lt;br /&gt;
Nello specifico, il mapping non avviene pi&amp;ugrave; tramite la costruzione di un XML da embeddare nel progetto, ma scrivendo semplice codice C#. Anche se tramite gli appositi XSD si pu&amp;ograve; disporre dell&amp;rsquo;intellisense durante la stesura dell&amp;rsquo;XML, l&amp;rsquo;approccio Fluent offre ulteriori vantaggi.&lt;/p&gt;
&lt;p&gt;La cosa pi&amp;ugrave; interessante &amp;egrave; che, nel caso di renaming di alcune propriet&amp;agrave;, si ha gi&amp;agrave; il mapping aggiornato, cosa che precedentemente al fluent era fattibile solo tramite l&amp;rsquo;uso di appositi plugin come Resharper: nel caso non si avesse avuto a disposizione questo addon spesso ci si imbatteva in alcuni problemi (come l&amp;rsquo;errata scrittura di una propriet&amp;agrave;) solo a runtime, mentre ora l&amp;rsquo;errore si avrebbe a compile time, con un vantaggio notevole per lo sviluppatore.    &lt;br /&gt;
Oltre a ci&amp;ograve;, grazie alle lambda, la scrittura del mapping &amp;egrave; molto pi&amp;ugrave; fluente (non a caso si chiama Fluent), come dimostra lo snippet seguente:&lt;/p&gt;
&lt;pre class="brush: csharp; ruler: true;"&gt;
public class CatMap : ClassMap&amp;lt;Cat&amp;gt;
{
  public CatMap()
  {
    Id(x =&amp;gt; x.Id);
    Map(x =&amp;gt; x.Name)
      .Length(16)
      .Not.Nullable();
    Map(x =&amp;gt; x.Sex);
    References(x =&amp;gt; x.Mate);
    HasMany(x =&amp;gt; x.Kittens);
  }
}&lt;/pre&gt;
&lt;p&gt;Personalmente ho iniziato ad usare il Fluent gi&amp;agrave; dalla versione 0.1 - praticamente la prima versione - con non pochi problemi relativamente alle composite unique key, ma ora che &amp;egrave; alla versione &lt;strong&gt;1.0 RC&lt;/strong&gt; (dal 16 di agosto), confido che i problemi siano risolti e che sia gi&amp;agrave; utilizzabile alla grande.&lt;/p&gt;
&lt;p&gt;Inoltre credo (qualcuno me lo ha detto, ma non ricordo chi) che il Fluent sia gi&amp;agrave; presente nella trunk di NHibernate 3, ma questa notizia prendetela con le pinze :)&lt;/p&gt;
&lt;p&gt;Ciauz&lt;/p&gt;
&lt;p&gt;Maggiori info sul Fluent le trovate &lt;a href="http://fluentnhibernate.org/"&gt;qui&lt;/a&gt; e &lt;a href="http://www.lostechies.com/blogs/jagregory/archive/2009/08/16/fluent-nhibernate-1-0rc.aspx"&gt;qui&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/uno-usertype-generico-per-gli-enums/"&gt;Uno UserType generico per gli Enums&lt;/a&gt; (9/11/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/fluentnhibernate-10-rtm/"&gt;FluentNHibernate 1.0 RTM&lt;/a&gt; (8/31/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/testare-il-mapping-di-nhibernate/"&gt;Testare il mapping di NHibernate&lt;/a&gt; (9/9/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/linqtonhibernate-10-is-out/"&gt;LinqToNHibernate 1.0 is Out&lt;/a&gt; (7/26/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/nhibernate-21-in-rtm/"&gt;NHibernate 2.1 in RTM&lt;/a&gt; (7/20/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/Fluent-NH-10-in-RC"&gt;&lt;strong&gt;More related document (8)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=SYKmMzV2DA8:sY7itpsYsiM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=SYKmMzV2DA8:sY7itpsYsiM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=SYKmMzV2DA8:sY7itpsYsiM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=SYKmMzV2DA8:sY7itpsYsiM:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=SYKmMzV2DA8:sY7itpsYsiM:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=SYKmMzV2DA8:sY7itpsYsiM:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=SYKmMzV2DA8:sY7itpsYsiM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=SYKmMzV2DA8:sY7itpsYsiM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=SYKmMzV2DA8:sY7itpsYsiM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=SYKmMzV2DA8:sY7itpsYsiM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=SYKmMzV2DA8:sY7itpsYsiM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=SYKmMzV2DA8:sY7itpsYsiM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=SYKmMzV2DA8:sY7itpsYsiM:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><link>http://imperugo.tostring.it/blog/post/fluent-nh-10-in-rc/</link><author>imperugo</author><comments>http://imperugo.tostring.it/blog/post/fluent-nh-10-in-rc/#feedback</comments><guid isPermaLink="true">http://imperugo.tostring.it/blog/post/fluent-nh-10-in-rc/</guid><pubDate>Sat, 22 Aug 2009 11:15:44 GMT</pubDate><category>Mapping</category><category>NHibernate</category><category>NHibernateFluent</category></item><item><title>LinqToNHibernate 1.0 is Out</title><description>&lt;p&gt;Lo ha annunciato &lt;a title="Ayende's Blog" href="http://ayende.com" rel="nofollow" target="_blank"&gt;Ayende&lt;/a&gt; in questo &lt;a title="NHibernate Linq 1.0 released" href="http://ayende.com/Blog/archive/2009/07/26/nhibernate-linq-1.0-released.aspx" rel="nofollow" target="_blank"&gt;post&lt;/a&gt;, mentre il download lo trovate &lt;a title="Linq To NHibernate" href="http://sourceforge.net/projects/nhibernate/files/NHibernate/2.1.0.GA/NHibernate.Linq-1.0.0.GA-bin.zip/download" rel="nofollow" target="_blank"&gt;qui&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ora non resta che provarlo.   &lt;br /&gt;
Stay Tuned!&lt;/p&gt;&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/fluentnhibernate-10-rtm/"&gt;FluentNHibernate 1.0 RTM&lt;/a&gt; (8/31/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/nhibernate-21-in-rtm/"&gt;NHibernate 2.1 in RTM&lt;/a&gt; (7/20/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/dto-il-e-reflection-nelle-nostre-applicazioni/"&gt;DTO, IL e Reflection nelle nostre applicazioni.&lt;/a&gt; (4/21/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/blinq-linq-to-bing/"&gt;BLinq (Linq to Bing)&lt;/a&gt; (8/23/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/foreach-ienumerable-of-t/"&gt;ForEach in un IEnumerable&lt;T&gt;&lt;/a&gt; (4/13/2010)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/LinqToNHibernate-10-is-Out"&gt;&lt;strong&gt;More related document (23)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=UOgy8S-4jb0:q_Rjmg9v-Ss:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=UOgy8S-4jb0:q_Rjmg9v-Ss:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=UOgy8S-4jb0:q_Rjmg9v-Ss:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=UOgy8S-4jb0:q_Rjmg9v-Ss:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=UOgy8S-4jb0:q_Rjmg9v-Ss:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=UOgy8S-4jb0:q_Rjmg9v-Ss:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=UOgy8S-4jb0:q_Rjmg9v-Ss:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=UOgy8S-4jb0:q_Rjmg9v-Ss:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=UOgy8S-4jb0:q_Rjmg9v-Ss:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=UOgy8S-4jb0:q_Rjmg9v-Ss:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=UOgy8S-4jb0:q_Rjmg9v-Ss:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=UOgy8S-4jb0:q_Rjmg9v-Ss:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=UOgy8S-4jb0:q_Rjmg9v-Ss:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><link>http://imperugo.tostring.it/blog/post/linqtonhibernate-10-is-out/</link><author>imperugo</author><comments>http://imperugo.tostring.it/blog/post/linqtonhibernate-10-is-out/#feedback</comments><guid isPermaLink="true">http://imperugo.tostring.it/blog/post/linqtonhibernate-10-is-out/</guid><pubDate>Sun, 26 Jul 2009 06:09:57 GMT</pubDate><category>Linq</category><category>LinqToNHibernate</category><category>Nhibernate</category><category>News</category></item><item><title>NHibernate 2.1 in RTM</title><description>&lt;p&gt;Forse sar&amp;agrave; una settimana intensa di RTM (Release to Manufacturing), ma intanto godiamoci la version 2.1 di &lt;strong&gt;NHibernate&lt;/strong&gt; appena annunciata da &lt;a target="_blank" rel="nofollow" href="http://ayende.com" title="Ayende's Blog"&gt;Ayende&lt;/a&gt; &lt;a target="_blank" rel="nofollow" href="http://ayende.com/Blog/archive/2009/07/20/nhibernate-2.1-is-out.aspx" title="NHibernate 2.1 is out!"&gt;qui&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Come detto da lui &amp;egrave; consigliato fare l&amp;rsquo;upgrade alla nuova versione che corregge numerosi Bug.&lt;/p&gt;
&lt;p&gt;Il download lo trovate &lt;a target="_blank" rel="nofollow" href="http://sourceforge.net/projects/nhibernate/files/" title="NHibernate 2.1 download."&gt;qui&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Enjoy.&lt;/p&gt;&lt;h2&gt;Related Content&lt;/h2&gt;&lt;ul&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/problema-con-nhibernate-e-table-for-hierarchy/"&gt;Problema con NHibernate e Table for Hierarchy&lt;/a&gt; (5/18/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/riflessioni-su-nhibernate/"&gt;Riflessioni su NHibernate&lt;/a&gt; (7/17/2006)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/gestione-schema-nhibernate/"&gt;Gestione dello schema database tramite NHibernate&lt;/a&gt; (12/13/2010)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/fluentnhibernate-10-rtm/"&gt;FluentNHibernate 1.0 RTM&lt;/a&gt; (8/31/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="http://imperugo.tostring.it/blog/post/linqtonhibernate-10-is-out/"&gt;LinqToNHibernate 1.0 is Out&lt;/a&gt; (7/26/2009)&lt;/li&gt;&lt;li style="list-style-type: none"&gt;&lt;a href="/Blog/Related/NHibernate-21-in-RTM"&gt;&lt;strong&gt;More related document (22)&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=616if6vf3TY:R7ijKSAaZBA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=616if6vf3TY:R7ijKSAaZBA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=616if6vf3TY:R7ijKSAaZBA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=616if6vf3TY:R7ijKSAaZBA:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=616if6vf3TY:R7ijKSAaZBA:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=616if6vf3TY:R7ijKSAaZBA:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=616if6vf3TY:R7ijKSAaZBA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=616if6vf3TY:R7ijKSAaZBA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=616if6vf3TY:R7ijKSAaZBA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=616if6vf3TY:R7ijKSAaZBA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=616if6vf3TY:R7ijKSAaZBA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?i=616if6vf3TY:R7ijKSAaZBA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/imperugo_ORM?a=616if6vf3TY:R7ijKSAaZBA:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/imperugo_ORM?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description><link>http://imperugo.tostring.it/blog/post/nhibernate-21-in-rtm/</link><author>imperugo</author><comments>http://imperugo.tostring.it/blog/post/nhibernate-21-in-rtm/#feedback</comments><guid isPermaLink="true">http://imperugo.tostring.it/blog/post/nhibernate-21-in-rtm/</guid><pubDate>Mon, 20 Jul 2009 15:29:03 GMT</pubDate><category>Nhibernate</category><category>News</category><category>ORM</category></item></channel></rss>
