<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Alan Northam : Tutorial</title><link>http://devlicio.us/blogs/alan_northam/archive/tags/Tutorial/default.aspx</link><description>Tags: Tutorial</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Custom Profile Provider with NHibernate</title><link>http://devlicio.us/blogs/alan_northam/archive/2007/08/09/custom-profile-provider-with-nhibernate.aspx</link><pubDate>Thu, 09 Aug 2007 13:29:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:37508</guid><dc:creator>anortham</dc:creator><slash:comments>9</slash:comments><description>&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; I&amp;#39;ve updated the NHibernate blog example code to include a custom profile provider.&amp;nbsp; This provider stores the profile information using the XML data type in SQL Server 2005.&amp;nbsp; New profile properties can be added to the web.config file in same way as the Microsoft SqlProfileProvider.&amp;nbsp; The included web.config contains examples showing how to add new properties and their types.&amp;nbsp;  If adding a custom type be sure to include the full type name (i.e. NHBlog.BusinessEntities.Security.Application.).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; The example now includes custom NHibernate based providers for Membership, Roles, and Profiles.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=37508" width="1" height="1"&gt;</description><enclosure url="http://devlicio.us" length="4151325" type="application/zip" /><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/Sql+Server/default.aspx">Sql Server</category><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/Tutorial/default.aspx">Tutorial</category><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/ProfileProvider/default.aspx">ProfileProvider</category></item><item><title>Getting Started with NHibernate: Part IV</title><link>http://devlicio.us/blogs/alan_northam/archive/2007/07/26/getting-started-with-nhibernate-part-iv.aspx</link><pubDate>Thu, 26 Jul 2007 20:07:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:35358</guid><dc:creator>anortham</dc:creator><slash:comments>11</slash:comments><description>&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; I&amp;#39;ve made some major changes to the blog application example.&amp;nbsp; The users and roles now use custom membership and role providers  that supports NHibernate.&amp;nbsp; Session context is maintained with a custom implementation of ICurrentSessionContext (a new NHibernate 1.2 feature).&amp;nbsp; The session and session factory management classes have also undergone some minor modifications.&amp;nbsp; I&amp;#39;ve also included a very basic web user interface that uses Ajax for Asp.Net (previously Atlas).&amp;nbsp; I&amp;#39;ll cover some of these topics in more detail in upcoming posts.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; The attached zip file contains the VS2005 solution and a SQL script to generate the database schema (SQL 2005 or SQL Express 2005 only).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=35358" width="1" height="1"&gt;</description><enclosure url="http://devlicio.us" length="3421081" type="application/x-zip-compressed" /><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/Sql+Server/default.aspx">Sql Server</category><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/Tutorial/default.aspx">Tutorial</category><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/MembershipUser/default.aspx">MembershipUser</category><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/RoleProvider/default.aspx">RoleProvider</category><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/MembershipProvider/default.aspx">MembershipProvider</category></item><item><title>Getting Started with NHibernate: Part III - Updated</title><link>http://devlicio.us/blogs/alan_northam/archive/2007/05/30/getting-started-with-nhibernate-part-iii-updated.aspx</link><pubDate>Wed, 30 May 2007 19:49:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:26912</guid><dc:creator>anortham</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;I&amp;#39;ve updated the mapping files for Comment and BlogPost in &lt;a href="http://devlicio.us/blogs/alan_northam/archive/2007/05/23/getting-started-with-nhibernate-part-iii.aspx" title="Getting Started with NHibernate: Part III"&gt;Part III&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The changes are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The named query GetCommentsByBlogPostID has been moved into the BlogPost.hbm.xml file, it just makes more sense for it to be there.&lt;/li&gt;
&lt;li&gt;&amp;lt;loader query-ref=&amp;quot;GetCommentsByBlogPostID&amp;quot;/&amp;gt; was added to the Comments collection mapping in the BlogPost.hbm.xml file, NHibernate will use this query when loading the collection.&lt;/li&gt;
&lt;li&gt; cascade=&amp;quot;delete&amp;quot;, and inverse=&amp;quot;true&amp;quot; attributes were added to the Comments collection mapping in the BlogPost.hbm.xml file, the combination of these two setting ensure that when a BlogPost is deleted all of the comments associated with it will also be deleted.&amp;nbsp; It is unlikely that you would want to delete a BlogPost and all it&amp;#39;s comments in a live blog application (although you might want to archive or hide them) but here it serves the purpose of demonstrating these attributes usage.&lt;/li&gt;
&lt;li&gt;The Comment mapping file (Comment.hbm.xml) was updated to include a stored procedure call for loading comment entities by ID.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These changes will be covered in greater detail as the application progresses.&amp;nbsp; Part IV is coming soon and will include all updates, source code, and SQL Express database.&lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=26912" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/Sql+Server/default.aspx">Sql Server</category><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/Tutorial/default.aspx">Tutorial</category></item><item><title>Getting Started with NHibernate: Part III</title><link>http://devlicio.us/blogs/alan_northam/archive/2007/05/23/getting-started-with-nhibernate-part-iii.aspx</link><pubDate>Wed, 23 May 2007 18:11:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:26324</guid><dc:creator>anortham</dc:creator><slash:comments>13</slash:comments><description>&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; When mapping objects to the database in NHibernate you can either use XML files or decorate your classes with mapping attributes (NHibernate.Mapping.Attributes).&amp;nbsp; I&amp;#39;ve used both but I usually choose XML files simply as a matter of personal preference.&amp;nbsp; Either method works well and both provide many options for defining the relationship between class and table and configuring it&amp;#39;s function.&amp;nbsp; I&amp;#39;ll be using XML files in this tutorial but may work in some mapping attributes later in the process.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; To get intellisense working with the mapping files you can copy the nhibernate-*.xsd files from the NHibernate source (NHibernate\src\NHibernate\) to C:\Program Files\Microsoft Visual Studio 8\Xml\Schemas (or wherever you installed VS).&amp;nbsp; There are a few tools that can help by generating the mapping files based on an existing database schema, one that I&amp;#39;ve had the most success with is &lt;a href="http://www.mygenerationsoftware.com" target="_blank"&gt;MyGeneration&lt;/a&gt; (try the template by lujan99).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; As I go through each mapping I&amp;#39;ll point out how certain features work but for detailed information on the available options check the &lt;a href="http://www.hibernate.org/hib_docs/nhibernate/html_single/#mapping-declaration" target="_blank"&gt;official documentation here&lt;/a&gt;.&amp;nbsp; Each of these mapping files will follow the naming convention classname.hbm.xml as this is what NHibernate expects to find when the SessionFactory is initialized (more on this in Part IV).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;BlogPost mapping:&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&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; 
      assembly=&amp;quot;NHBlog.Domain&amp;quot; namespace=&amp;quot;NHBlog.Domain&amp;quot;&amp;gt;
  &amp;lt;class name=&amp;quot;BlogPost&amp;quot; table=&amp;quot;BlogPost&amp;quot;&amp;gt;
    &amp;lt;id name=&amp;quot;ID&amp;quot; column=&amp;quot;ID&amp;quot; type=&amp;quot;int&amp;quot;&amp;gt;
      &amp;lt;generator class=&amp;quot;native&amp;quot; /&amp;gt;
    &amp;lt;/id&amp;gt;
    &amp;lt;property name=&amp;quot;Title&amp;quot; column=&amp;quot;Title&amp;quot; type=&amp;quot;string&amp;quot; not-null=&amp;quot;true&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
    &amp;lt;property name=&amp;quot;Body&amp;quot; column=&amp;quot;Body&amp;quot; type=&amp;quot;string&amp;quot; not-null=&amp;quot;true&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
    &amp;lt;property name=&amp;quot;PublishedOn&amp;quot; column=&amp;quot;PublishedOn&amp;quot; type=&amp;quot;DateTime&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
    &amp;lt;many-to-one name=&amp;quot;PublishedBy&amp;quot; column=&amp;quot;PublishedByID&amp;quot; class=&amp;quot;BlogUser&amp;quot; not-null=&amp;quot;true&amp;quot; /&amp;gt;
    &amp;lt;bag name=&amp;quot;Comments&amp;quot; cascade=&amp;quot;delete&amp;quot; inverse=&amp;quot;true&amp;quot; &amp;gt;
      &amp;lt;key column=&amp;quot;BlogPostID&amp;quot; /&amp;gt;
      &amp;lt;one-to-many class=&amp;quot;Comment&amp;quot; /&amp;gt;
      &amp;lt;loader query-ref=&amp;quot;GetCommentsByBlogPostID&amp;quot;/&amp;gt;
    &amp;lt;/bag&amp;gt;
  &amp;lt;/class&amp;gt;
  &amp;lt;sql-query name=&amp;quot;GetCommentsByBlogPostID&amp;quot;&amp;gt;
    &amp;lt;load-collection alias=&amp;quot;Comments&amp;quot; role=&amp;quot;BlogPost.Comments&amp;quot; /&amp;gt;
    exec GetCommentsByBlogPostID :blogPostID
  &amp;lt;/sql-query&amp;gt;
&amp;lt;/hibernate-mapping&amp;gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; At the beginning of the file I&amp;#39;m setting the assembly and namespace values.&amp;nbsp; They aren&amp;#39;t required, but if they are not set you will need to fully qualify any class names used including the assembly ( i.e., NHBlog.Domain.BlogPost, NHBlog.Domain).&amp;nbsp; The class element tells NHibernate what the name of the class is and which table that class maps to, in this case both are named BlogPost.&amp;nbsp; The id element defines the primary key of the table and which property in the class it maps to.&amp;nbsp; It&amp;#39;s also includes the type (.net data type) and which class is generating these values.&amp;nbsp; NHibernate includes many different &lt;a href="http://www.hibernate.org/hib_docs/nhibernate/html_single/#mapping-declaration-id-generator" target="_blank"&gt;generator&lt;/a&gt; classes.&amp;nbsp; In our example we are using the identity function in SQL Server so the generator is set to native.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Each BlogPost will also have a collection of Comments seen here mapped using the bag element.&amp;nbsp; This mapping is a bit different than normal in that the&amp;lt;loader query-ref=&amp;quot;GetCommentsByBlogPostID&amp;quot;/&amp;gt; attribute specifies which query to use to load the collection of comments, in this case a stored
procedure.&amp;nbsp; At the bottom of the file a
sql-query is defined to execute the stored procedure
GetCommentsByBlogPostID and pass in the value blogPostID.&amp;nbsp; The
load-collection element instructs NHibernate what type of entities to expect as the result of this query.
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Why am I using a stored procedure here?&amp;nbsp; I don&amp;#39;t have to, I
could load the collection like any other but doing it this way serves
two purposes; to demonstrate the use of stored procedures (a new
feature in NHibernate 1.2), and to assist in loading the comments in a
threaded conversational manner (see the requirements in &lt;a href="http://devlicio.us/blogs/alan_northam/archive/2007/05/22/getting-started-with-nhibernate-part-ii.aspx" target="_blank"&gt;Part II&lt;/a&gt;).&amp;nbsp;
GetCommentsByBlogPost uses a feature in Sql Server 2005 (and Sql
Express 2005) called Common Table Expressions.&amp;nbsp; More information can be
found &lt;a href="http://msdn2.microsoft.com/en-us/library/ms345144.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;BlogUser mapping:&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&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; 
      assembly=&amp;quot;NHBlog.Domain&amp;quot; namespace=&amp;quot;NHBlog.Domain&amp;quot;&amp;gt;
  &amp;lt;class name=&amp;quot;BlogUser&amp;quot; table=&amp;quot;BlogUser&amp;quot;&amp;gt;
    &amp;lt;id name=&amp;quot;ID&amp;quot; column=&amp;quot;ID&amp;quot; type=&amp;quot;int&amp;quot;&amp;gt;
      &amp;lt;generator class=&amp;quot;native&amp;quot; /&amp;gt;
    &amp;lt;/id&amp;gt;
    &amp;lt;property name=&amp;quot;FirstName&amp;quot; column=&amp;quot;FirstName&amp;quot; type=&amp;quot;string&amp;quot; not-null=&amp;quot;true&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
    &amp;lt;property name=&amp;quot;LastName&amp;quot; column=&amp;quot;LastName&amp;quot; type=&amp;quot;string&amp;quot; not-null=&amp;quot;true&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
    &amp;lt;property name=&amp;quot;Alias&amp;quot; column=&amp;quot;Alias&amp;quot; type=&amp;quot;string&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
    &amp;lt;property name=&amp;quot;EmailAddress&amp;quot; column=&amp;quot;EmailAddress&amp;quot; type=&amp;quot;string&amp;quot; not-null=&amp;quot;true&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
    &amp;lt;property name=&amp;quot;CreatedOn&amp;quot; column=&amp;quot;CreatedOn&amp;quot; type=&amp;quot;DateTime&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
    &amp;lt;bag name=&amp;quot;BlogPosts&amp;quot;&amp;gt;
      &amp;lt;key column=&amp;quot;PublishedByID&amp;quot; /&amp;gt;
      &amp;lt;one-to-many class=&amp;quot;BlogPost&amp;quot; /&amp;gt;
    &amp;lt;/bag&amp;gt;
    &amp;lt;bag name=&amp;quot;Comments&amp;quot;&amp;gt;
      &amp;lt;key column=&amp;quot;MadeByID&amp;quot; /&amp;gt;
      &amp;lt;one-to-many class=&amp;quot;Comment&amp;quot; /&amp;gt;
    &amp;lt;/bag&amp;gt;
    &amp;lt;bag name=&amp;quot;BlogRoles&amp;quot; table=&amp;quot;UserRole&amp;quot;&amp;gt;
      &amp;lt;key column=&amp;quot;BlogUserID&amp;quot; /&amp;gt;
      &amp;lt;many-to-many class=&amp;quot;BlogRole&amp;quot; column=&amp;quot;BlogRoleID&amp;quot; /&amp;gt;
    &amp;lt;/bag&amp;gt;
  &amp;lt;/class&amp;gt;
&amp;lt;/hibernate-mapping&amp;gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; In BlogUser we have three collections mapped; BlogPosts, Comments, and BlogRoles.&amp;nbsp; The first two are one-to-many relationships meaning that a single BlogUser can have posted many BlogPosts and made many Comments.&amp;nbsp; The last is a many-to-many relationship meaning that a BlogUser can belong to many BlogRoles and a BlogRole can contain many BlogUsers.&amp;nbsp; The table UserRole defines this relationship in the database.&amp;nbsp; The mapping instructs NHibernate what type of class makes up this collection, which table to use to look up the collection members and which column holds the key for each.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;BlogRole mapping:&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&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; 
      assembly=&amp;quot;NHBlog.Domain&amp;quot; namespace=&amp;quot;NHBlog.Domain&amp;quot;&amp;gt;
  &amp;lt;class name=&amp;quot;BlogRole&amp;quot; table=&amp;quot;BlogRole&amp;quot;&amp;gt;
    &amp;lt;id name=&amp;quot;ID&amp;quot; column=&amp;quot;ID&amp;quot; type=&amp;quot;int&amp;quot;&amp;gt;
      &amp;lt;generator class=&amp;quot;native&amp;quot; /&amp;gt;
    &amp;lt;/id&amp;gt;
    &amp;lt;property name=&amp;quot;Name&amp;quot; column=&amp;quot;Name&amp;quot; type=&amp;quot;string&amp;quot; not-null=&amp;quot;true&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
    &amp;lt;bag name=&amp;quot;BlogUsers&amp;quot; table=&amp;quot;UserRole&amp;quot;&amp;gt;
      &amp;lt;key column=&amp;quot;BlogRoleID&amp;quot; /&amp;gt;
      &amp;lt;many-to-many class=&amp;quot;BlogUser&amp;quot; column=&amp;quot;BlogUserID&amp;quot; /&amp;gt;
    &amp;lt;/bag&amp;gt;
  &amp;lt;/class&amp;gt;
&amp;lt;/hibernate-mapping&amp;gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BlogRole has a collection of BlogUsers which represents the other side of the many-to-many relationship defined in BlogUser.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp; &lt;b&gt;Comment mapping:&lt;/b&gt;&lt;/p&gt;
&lt;p&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;
      assembly=&amp;quot;NHBlog.Domain&amp;quot; namespace=&amp;quot;NHBlog.Domain&amp;quot;&amp;gt;
  &amp;lt;class name=&amp;quot;Comment&amp;quot; table=&amp;quot;Comment&amp;quot;&amp;gt;
    &amp;lt;id name=&amp;quot;ID&amp;quot; column=&amp;quot;ID&amp;quot; type=&amp;quot;int&amp;quot;&amp;gt;
      &amp;lt;generator class=&amp;quot;native&amp;quot; /&amp;gt;
    &amp;lt;/id&amp;gt;
    &amp;lt;property name=&amp;quot;Subject&amp;quot; column=&amp;quot;Subject&amp;quot; type=&amp;quot;string&amp;quot; not-null=&amp;quot;true&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
    &amp;lt;property name=&amp;quot;Body&amp;quot; column=&amp;quot;Body&amp;quot; type=&amp;quot;string&amp;quot; not-null=&amp;quot;true&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
    &amp;lt;property name=&amp;quot;MadeOn&amp;quot; column=&amp;quot;MadeOn&amp;quot; type=&amp;quot;DateTime&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
    &amp;lt;many-to-one name=&amp;quot;MadeBy&amp;quot; column=&amp;quot;MadeByID&amp;quot; class=&amp;quot;BlogUser&amp;quot; not-null=&amp;quot;true&amp;quot; /&amp;gt;
    &amp;lt;many-to-one name=&amp;quot;InReplyTo&amp;quot; column=&amp;quot;InReplyToID&amp;quot; class=&amp;quot;Comment&amp;quot; /&amp;gt;
    &amp;lt;many-to-one name=&amp;quot;BlogPost&amp;quot; column=&amp;quot;BlogPostID&amp;quot; class=&amp;quot;BlogPost&amp;quot; not-null=&amp;quot;true&amp;quot; /&amp;gt;
    &amp;lt;bag name=&amp;quot;Replies&amp;quot;&amp;gt;
      &amp;lt;key column=&amp;quot;InReplyToID&amp;quot; /&amp;gt;
      &amp;lt;one-to-many class=&amp;quot;Comment&amp;quot; /&amp;gt;
    &amp;lt;/bag&amp;gt;
    &amp;lt;property name=&amp;quot;IsVisible&amp;quot; column=&amp;quot;IsVisible&amp;quot; type=&amp;quot;Boolean&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
    &amp;lt;property name=&amp;quot;Depth&amp;quot; column=&amp;quot;Depth&amp;quot; type=&amp;quot;int&amp;quot; insert=&amp;quot;false&amp;quot; update=&amp;quot;false&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;
    &amp;lt;loader query-ref=&amp;quot;GetCommentByID&amp;quot;/&amp;gt;
  &amp;lt;/class&amp;gt;
  &amp;lt;sql-query name=&amp;quot;GetCommentByID&amp;quot;&amp;gt;
    &amp;lt;return class=&amp;quot;Comment&amp;quot;&amp;gt;&amp;lt;/return&amp;gt;
    exec GetCommentByID :id
  &amp;lt;/sql-query&amp;gt;
&amp;lt;/hibernate-mapping&amp;gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; A Comment has a reference to the BlogUser who made it (MadeBy), the Comment it is replying to (InReplyTo), if any, the BlogPost it is a comment on (BlogPost), and a collection of comments replying to it (Replies).&amp;nbsp; Also, notice the &amp;quot;Depth&amp;quot; property doesn&amp;#39;t allow inserting or updating of this value.&amp;nbsp; That&amp;#39;s because this value/column doesn&amp;#39;t actually exist in the database, it&amp;#39;s generated when loading a collection of comments.&amp;nbsp; If you load an individual Comment this value will always be zero.&amp;nbsp; This mapping is also using a stored procedure but in this case it will be used when loading a comment by id.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;GetCommentsByBlogPostID stored procedure code:&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
CREATE PROCEDURE [dbo].[GetCommentsByBlogPostID] 
(
	@blogPostID int = 0
)
AS
	
SET NOCOUNT ON;
WITH CommentList ( ID, [Subject], Body, MadeOn, 
			        MadeByID, InReplyToID, BlogPostID, 
					IsVisible, Depth, sortcol) 
AS 
( SELECT  ID, [Subject], Body, MadeOn, 
  MadeByID, InReplyToID, BlogPostID, IsVisible, 0, CAST(ID AS VARBINARY(900)) 
FROM    Comment
WHERE   (InReplyToID IS NULL) AND (BlogPostID = @blogPostID)
                              
UNION ALL
                              
SELECT  c.ID, c.Subject, c.Body, c.MadeOn, 
  c.MadeByID, c.InReplyToID, c.BlogPostID, c.IsVisible, cl.depth + 1, 
      CAST(cl.sortcol + CAST(c.ID AS BINARY(4)) AS VARBINARY(900))
FROM    Comment AS c INNER JOIN
      CommentList AS cl ON c.InReplyToID = cl.ID)
               
SELECT  ID, [Subject], Body, MadeOn, 
  MadeByID, InReplyToID, BlogPostID, IsVisible, Depth
FROM    CommentList
ORDER BY sortcol
	              
RETURN
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;GetCommentByID stored procedure code:&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
CREATE PROCEDURE dbo.GetCommentByID(
@id int
)
AS
SET NOCOUNT ON
SELECT ID, Subject, Body, MadeOn, MadeByID, InReplyToID, BlogPostID, IsVisible, 0 as Depth
FROM Comment
WHERE ID = @id
RETURN

&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; In Part IV we will configure NHibernate and begin building the supporting framework needed to use what we have done so far.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=26324" width="1" height="1"&gt;</description><enclosure url="http://devlicio.us" length="228798" type="application/zip" /><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/Sql+Server/default.aspx">Sql Server</category><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/Tutorial/default.aspx">Tutorial</category></item><item><title>Getting Started with NHibernate: Part II</title><link>http://devlicio.us/blogs/alan_northam/archive/2007/05/22/getting-started-with-nhibernate-part-ii.aspx</link><pubDate>Wed, 23 May 2007 01:26:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:26234</guid><dc:creator>anortham</dc:creator><slash:comments>4</slash:comments><description>&lt;div class="ExternalClass290CB33CC9034E9F9D9E0EA6EFAED5FA"&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; While writing the code necessary for this installment, I found myself 
falling prey to feature-creep.&amp;nbsp; So I&amp;#39;ve decided to keep it fairly simple in the 
beginning.&amp;nbsp; However, once the basic components are working I&amp;#39;ll start 
introducing more features.&amp;nbsp; I thought this might be a good way to demonstrate 
what is and isn&amp;#39;t required to add new functionality to a working NHibernate 
application.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; The application&amp;#39;s initial functionality will consist of blog users being 
able to post new blog posts, comment on posts,&amp;nbsp; and reply to other comments.&amp;nbsp; 
Only users with the correct role membership will be able to post, all users will 
be able to comment and reply to comments.&amp;nbsp; Also, the comments should be threaded 
so conversations can be followed more easily.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; The domain model has just 4 classes (for now):&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="http://devlicio.us/photos/devlicious/images/26312/original.aspx" title="NHBlog UML diagram" alt="NHBlog UML diagram" height="376" width="375" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; The Sql Express 2005 database&amp;nbsp;will have 5 tables&amp;nbsp;persisting our 4 
classes.&amp;nbsp; The extra database table&amp;nbsp;UserRole&amp;nbsp;will persist the many-to-many 
relationship between BlogUser and BlogRole.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://devlicio.us/photos/devlicious/images/26313/original.aspx" title="NHBlog database diagram" alt="NHBlog database diagram" height="561" width="430" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Also notice that the&amp;nbsp;&amp;quot;Depth&amp;quot; property in the Comment class is not 
actually persisted, it is a read-only value that is generated when a collection 
of comments for a BlogPost is loaded and represents the&amp;nbsp;level of the comment in 
the comment hierarchy (threaded convesations!).&amp;nbsp; See the attachment for the database script.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; In Part III we will create the mapping glue that binds the model and 
database together.&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=26234" width="1" height="1"&gt;</description><enclosure url="http://devlicio.us" length="1722" type="application/zip" /><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/Tutorial/default.aspx">Tutorial</category></item><item><title>Getting Started with NHibernate: Part I</title><link>http://devlicio.us/blogs/alan_northam/archive/2007/05/19/getting-started-with-nhibernate-part-i.aspx</link><pubDate>Sun, 20 May 2007 02:22:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:25898</guid><dc:creator>anortham</dc:creator><slash:comments>12</slash:comments><description>&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; When I first started learning and using NHibernate, I read every tutorial, downloaded every example, and studied every code snippet I could get my hands on.&amp;nbsp; There are some great resources available with one of the best being &lt;a href="http://devlicio.us/blogs/billy_mccafferty/default.aspx" target="_blank"&gt;Billy McCafferty&amp;#39;s&lt;/a&gt; &lt;a href="http://www.codeproject.com/aspnet/NHibernateBestPractices.asp" target="_blank"&gt;NHibernate Best Practices.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In my opinion, the majority of the resources available fall into one of three categories:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Articles that expect and require some familiarity with NHibernate.&lt;/li&gt;
&lt;li&gt;Articles or snippets/sample code that are written at such a low level, you&amp;#39;re left wondering how the technique demonstrated would be implemented in real world code.&lt;/li&gt;
&lt;li&gt;Open source code that dissecting and learning from would be a daunting and tedious task for users new to the concept of NHibernate.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Each of the resources I refer to provide a lot of useful information.&amp;nbsp; However, I like to learn by doing and I think a tutorial that provides a step by step guide to implementing NHibernate in a real world application would be beneficial to a lot of prospective NHibernate users.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; In an attempt to fill this void, this is the first article in a series of many.&amp;nbsp; Each article will cover a bite-sized (byte-sized?) step in the process as we design and implement a blog.&amp;nbsp; We will finish with an application that is simple enough that we don&amp;#39;t get bogged down in unrelated topics but complex enough that in the end we will have a framework that can be used as the foundation for future projects.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; In Part II we will build our domain classes.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=25898" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://devlicio.us/blogs/alan_northam/archive/tags/Tutorial/default.aspx">Tutorial</category></item></channel></rss>