Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious

Alan Northam

  • Practical Implementation - spending some cache.

    Take a look at my previous post for the details on a cache helper method that I like to use.  In this post, we'll be putting it to work (the word for today is J - O - B).  Here's a look at the code for reference.


    Enter the ASP.NET AJAX AutoComplete Extender.  It's a perfect candidate for a little cache help.  I certainly wouldn't want the database being hit every time a user typed the next letter in the autocomplete box.  I apologize for wearing you down with all this talk.  I think I've said too much.  Let's look at the code for autocomplete webservice.


    The webservice takes the first part of the prefixText (minimumPrefixLength should match the value in the autocomplete extender control) and queries the database for all matches.  It stores that result set in cache and then filters the list by prefixText if needed.  Finally it will take the top X (count is specified by the control) and return it to the control.

    If a user was searching for "automobile", after typing a-u-t all possible results would be cache so that each successive letter will not hit the database.  Another database hit will be incurred when a user searches for a different 3 letter prefix. 

    I'm attaching the full sample code along with a Sql Express database that contains some huge word list I found online (to be attached later, technical difficulties).  Enjoy and try not to spend it all in one place.
     

  • Cold, Hard, Cache!

    Don't get me wrong, I really like the Asp.Net Cache (or HttpRuntime.Cache or Uncle Daddy if you want to call it that... you're a little odd aren't you?), but sometimes it just can't be trusted.  I mean, I just gave you (the cache) my precious object a second ago and now you claim you don't have it?  Did you lose it?  Did you sell it on eBay?  Did you pawn it to support your habit?  Please at least tell me you got a decent price for it. 

    One of the great things about the cache is also what makes it so untrustworthy.   Objects stored there are referenced with WeakReference so if your sever starts getting low on memory GC will collect objects from the cache to free some up.  Also take into account that if you put an object in Cache and set it to expire after X minutes, when you go back to retreive it, do you really know how long it's been?

    So what we want is a way to tell the cache "I want this specific object (a yellow Tonka dumptruck, metal, not plastic) and if you don't have it, here are instructions on how to get it".

    Something like this:

    Usage would look like this:

    I call it the code equivalent of "Trust but verify".

  • ADO.NET, Nullable Types, Casting DBNull and You

    I know this may be a little too scary for some of you so I apologize in advance.  Take a deep breath and try to imagine that you can't use NHibernate and you're stuck using ADO.NET (circa 2001, did they even have computers back then?). 

    If you've ever tried to read the value from a column in a datarow, you've probably run into something like this (a quick Google search will bring up page after page of variations):


    Wow, that's ugly. What if I have several nullable columns? What if I have a lot of nullable columns? There has to be a better way.

    Let's suppose I have a class MyClass (original huh?) and it has a nullable DateTime property and a nullable integer property.


    I like a good one line solution.  Of course, you really can't cast DBNull.Value (which would be the value of row["ColumnX"]  if the column is null in the database) as a nullable int (or DateTime?).  (edit: thanks Chris) The cast above is actually failing but casting with "as" doesn't throw an exception and returns a null value which is just what we want.

    "as"... you're my hero...*sniff* 

     

  • Databinding performance tip in ASP.NET

        In my last post I mentioned the use of C style casting when databinding in ASP.NET.  That got me thinking about the performance differences between the two main ways to bind data in controls with custom templates (GridView, DataList, Repeater, etc). 

        In my example I'm using a DataList and by default, Visual Studio will bind the data to your template controls using the "Eval" method.

        This method uses reflection and can be considerably slower depending on the complexity of your template and the number of properties you are binding.  The attached code uses a very simple DataList with simple data.  To see the difference in performance you'll need to increase the size of the data using the drop down list at the top.

        Compare the performance using the "Eval" method to using the C style cast to access your object's properties.

    EDIT:  As Bill pointed out in the comments, the call to DataBinder.GetDataItem() isn't necessary as you have access through the container already.  I've updated the attached test code to include all three methods.  These last two being equal in performance in my testing.


        In my testing this method (the last two methods, actually) was (were) 3 - 4 times faster.  As I said, this depends on the complexity of your control. 

  • Casting options in C#

        What is the best way to cast from one type to another in C#?  This question came up at work last week while I was looking through some older code.  The code in question was using the C style casting syntax.  I have started to use the "as" style cast more often and rewrote it.  Then I decided to do some research into the differences between the two styles to find out if one really is better than the other.

        The most obvious difference is that a C style case will throw and exception if the cast fails and the "as" style cast will simply return null.  So first you need to take into consideration what these differences will have on your code.  Will you need to wrap every cast in try/catch blocks?  Not if you use the "as" style, but you will need to check for null.  What about performance?

        I read a dozen or so blog posts on the subject and they seemed to be pretty evenly divided with half insisting that one style was obviously superior and the other half convinced their chosen style was better.  That didn't really help so I decided to do some testing on my own.

        I've attached a small test project for reference, it will allow you to select the number of casts to perform and the style and return the total time and average for each cast.  First let's see what the difference looks like in IL (o is of type object in these examples).

       So there is a difference at the IL level but is one a better performer?  I wrote three different test projects, the last of which you will find attached to this post.  Why did I write three?  Because with each test I was convinced that my results must be skewed because I was not seeing the  performance difference I expected.  I ran test casting 100,000, 1,000,000, 10,000,000 and 100,000,000 objects many times in difference orders, restarting the application between tests, not restarting between tests, clicking the button with my left hand, clicking with my right hand, every combination I could think of.

        What did I discover?  It was pretty anticlimactic.  In my opinion the difference was completely negligible.  That is, negligible if you aren't throwing exceptions when casting with the C style cast.  The most stable set of test results I could get were casting 1,000,000 objects.  In this case, either style averaged 10.1 seconds total and averaged 0.0101 milliseconds.  We're talking about a difference of 0.00005 milliseconds per cast.  I can't really get worked up over that.  Of course, if you throw exceptions for each C style cast in that test, it's over 10 times slower.  That's something to consider!

       So will I pick one over the other?  The answer is an emphatic "meh".  In code I will probably use the "as" style.  When doing things in markup related to databinding it's extremely useful to be able to use the C style cast and I will continue to do so.

     

    Posted Oct 07 2007, 02:27 PM by anortham with 9 comment(s)
    Filed under: , ,
  • WCF and NHibernate

         If you've tried to pass NHibernate objects over the wire using a webservice before, you know how painful it can be.  But what about WCF?  Can it ease your pain?  Well, yes, of course it can.  This wouldn't be a very interesting post if the answer was no.

         There are three main issues that needed to be fixed:  serializing circular references, passing generic list to the client (and not having them converted to arrays), and serializing NHibernate/Castle proxy objects.

    Serializing circular references.

         An example of a circular reference would be a User object that has a collection of Roles and each of those Role objects has a collection of User objects.  In the past (with webservices) this meant you had to decorate the offending properties with [XMLIgnore] to serialize your objects.  This meant that your object graph would be quite different over the wire.

         Let's not dwell on the past.  The DataContractSerializer can preserve your object references, but not by default.  You're going to need to extend DataContractSerializerOperationBehavior as described here in an excellent article by James Kovacs.  The code included with this post is built using his example.

    Passing generic collections to the client.

         Specifically, I’m talking about passing objects that contain collections implemented as IList<T> as is necessary to use generics with NHibernate.  This was actually a two part problem.  The default serialization in ASP.NET webservices (XMLSerializer) could not serialize an interface and even when casting to List<T> the client would see the collection as an array, not a generic list.  In WCF, the DataContractSerializer can serialize IList<T>.  Getting the client to see the collection properly requires you to generate your service proxies using the command line utility svcutil.exe (you can’t do it using the IDE in VS2005, but you will be able to in VS2008).  The command will look something like this (notice the /ct switch, a shortened form of the switch /collectiontype):

    Serializing NHibernate/Castle proxies.

         I’m going to save this topic for a separate post.  Actually, I’m still testing and getting some unexpected results that I need to quantify first.  For now, download the sample code included with this post and try it for yourself. 

    Notes about the sample code.

         If this is the first time you are running this app (it’s an extension of the sample code from my previous posts) you will need to make sure and add an initial application to the “Applications” table in the database setting the application name to “NHBlog”.  This is a requirement of the custom MembershipProvider included in the sample.

         This code has been used and reused and modified many times.  As a result, it may have some rough edges in the presentation but the underlying framework should be solid.

  • Custom Profile Provider with NHibernate

        I've updated the NHibernate blog example code to include a custom profile provider.  This provider stores the profile information using the XML data type in SQL Server 2005.  New profile properties can be added to the web.config file in same way as the Microsoft SqlProfileProvider.  The included web.config contains examples showing how to add new properties and their types.  If adding a custom type be sure to include the full type name (i.e. NHBlog.BusinessEntities.Security.Application.).

        The example now includes custom NHibernate based providers for Membership, Roles, and Profiles.

  • Getting Started with NHibernate: Part IV

        I've made some major changes to the blog application example.  The users and roles now use custom membership and role providers that supports NHibernate.  Session context is maintained with a custom implementation of ICurrentSessionContext (a new NHibernate 1.2 feature).  The session and session factory management classes have also undergone some minor modifications.  I've also included a very basic web user interface that uses Ajax for Asp.Net (previously Atlas).  I'll cover some of these topics in more detail in upcoming posts.

        The attached zip file contains the VS2005 solution and a SQL script to generate the database schema (SQL 2005 or SQL Express 2005 only).
     

  • Support a great charity and fellow developer

    Visit MillionCount.com and help fellow developer Jeremy Harper raise money for PUSH America by counting to one million.
  • Getting Started with NHibernate: Part III - Updated

    I've updated the mapping files for Comment and BlogPost in Part III.

    The changes are:

    1. The named query GetCommentsByBlogPostID has been moved into the BlogPost.hbm.xml file, it just makes more sense for it to be there.
    2. <loader query-ref="GetCommentsByBlogPostID"/> was added to the Comments collection mapping in the BlogPost.hbm.xml file, NHibernate will use this query when loading the collection.
    3. cascade="delete", and inverse="true" 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.  It is unlikely that you would want to delete a BlogPost and all it'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.
    4. The Comment mapping file (Comment.hbm.xml) was updated to include a stored procedure call for loading comment entities by ID.

    These changes will be covered in greater detail as the application progresses.  Part IV is coming soon and will include all updates, source code, and SQL Express database.

     

  • Getting Started with NHibernate: Part III

        When mapping objects to the database in NHibernate you can either use XML files or decorate your classes with mapping attributes (NHibernate.Mapping.Attributes).  I've used both but I usually choose XML files simply as a matter of personal preference.  Either method works well and both provide many options for defining the relationship between class and table and configuring it's function.  I'll be using XML files in this tutorial but may work in some mapping attributes later in the process. 

        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).  There are a few tools that can help by generating the mapping files based on an existing database schema, one that I've had the most success with is MyGeneration (try the template by lujan99).

        As I go through each mapping I'll point out how certain features work but for detailed information on the available options check the official documentation here.  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).

     

        BlogPost mapping: 

        At the beginning of the file I'm setting the assembly and namespace values.  They aren'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).  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.  The id element defines the primary key of the table and which property in the class it maps to.  It's also includes the type (.net data type) and which class is generating these values.  NHibernate includes many different generator classes.  In our example we are using the identity function in SQL Server so the generator is set to native. 

        Each BlogPost will also have a collection of Comments seen here mapped using the bag element.  This mapping is a bit different than normal in that the<loader query-ref="GetCommentsByBlogPostID"/> attribute specifies which query to use to load the collection of comments, in this case a stored procedure.  At the bottom of the file a sql-query is defined to execute the stored procedure GetCommentsByBlogPostID and pass in the value blogPostID.  The load-collection element instructs NHibernate what type of entities to expect as the result of this query.

        Why am I using a stored procedure here?  I don'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 Part II).  GetCommentsByBlogPost uses a feature in Sql Server 2005 (and Sql Express 2005) called Common Table Expressions.  More information can be found here.

     

        BlogUser mapping: 

        In BlogUser we have three collections mapped; BlogPosts, Comments, and BlogRoles.  The first two are one-to-many relationships meaning that a single BlogUser can have posted many BlogPosts and made many Comments.  The last is a many-to-many relationship meaning that a BlogUser can belong to many BlogRoles and a BlogRole can contain many BlogUsers.  The table UserRole defines this relationship in the database.  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.

     

        BlogRole mapping: 

         BlogRole has a collection of BlogUsers which represents the other side of the many-to-many relationship defined in BlogUser. 

     

       Comment mapping:

        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).  Also, notice the "Depth" property doesn't allow inserting or updating of this value.  That's because this value/column doesn't actually exist in the database, it's generated when loading a collection of comments.  If you load an individual Comment this value will always be zero.  This mapping is also using a stored procedure but in this case it will be used when loading a comment by id. 

     

        GetCommentsByBlogPostID stored procedure code: 

       

        GetCommentByID stored procedure code: 

       

        In Part IV we will configure NHibernate and begin building the supporting framework needed to use what we have done so far.

  • Getting Started with NHibernate: Part II

        While writing the code necessary for this installment, I found myself falling prey to feature-creep.  So I've decided to keep it fairly simple in the beginning.  However, once the basic components are working I'll start introducing more features.  I thought this might be a good way to demonstrate what is and isn't required to add new functionality to a working NHibernate application.

        The application's initial functionality will consist of blog users being able to post new blog posts, comment on posts,  and reply to other comments.  Only users with the correct role membership will be able to post, all users will be able to comment and reply to comments.  Also, the comments should be threaded so conversations can be followed more easily.

        The domain model has just 4 classes (for now):

     

     NHBlog UML diagram

     

       

        The Sql Express 2005 database will have 5 tables persisting our 4 classes.  The extra database table UserRole will persist the many-to-many relationship between BlogUser and BlogRole. 

     

    NHBlog database diagram

     

        Also notice that the "Depth" 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 level of the comment in the comment hierarchy (threaded convesations!).  See the attachment for the database script.

        In Part III we will create the mapping glue that binds the model and database together.

  • Getting Started with NHibernate: Part I

        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.  There are some great resources available with one of the best being Billy McCafferty's NHibernate Best Practices.

    In my opinion, the majority of the resources available fall into one of three categories:

    1. Articles that expect and require some familiarity with NHibernate.
    2. Articles or snippets/sample code that are written at such a low level, you're left wondering how the technique demonstrated would be implemented in real world code.
    3. Open source code that dissecting and learning from would be a daunting and tedious task for users new to the concept of NHibernate.

        Each of the resources I refer to provide a lot of useful information.  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.

        In an attempt to fill this void, this is the first article in a series of many.  Each article will cover a bite-sized (byte-sized?) step in the process as we design and implement a blog.  We will finish with an application that is simple enough that we don'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.

        In Part II we will build our domain classes.

More Posts

Our Sponsors

Red-Gate!