Object Reference .NET

ref this.Object

NHibernate and Execution Plans

clock October 26, 2009 11:29 by author Naz

Lately we have been investigating ORM’s (Object Relational Mapping) frameworks for use on a large enterprise level website which we been given the rare opportunity to rebuild from the ground up in Microsoft MVC.

I’ve used Subsonic in the past while working with dashCommerce and more recently on my latest project based on the wonderful Subsonic 3.0. We decided we needed something more robust and proven with a large enterprise level system like ours which currently comprises with hundreds of tables and store procedures all managed by a team of professional DBA’s who do a pretty good job at optimising and tuning the Microsoft SQL 2005 database.

After much deliberation we managed to convince the DBAs and Developer Head to give NHibernate a shot. It seemed to be the most mature fully featured ORM for .NET and rated highly whitin the .NET community as is apparent by the huge number of blog posts about it, so we felt more secure choosing it over the premature Entity Framework.

NHibernate and MVC brought us to reconsider our architecture and after finally getting my head around to the S#harp Architecture I managed to convince the team it was the way to go and gave us a good foundation to build our application on.

After a few weeks we got a really good prototype working. We mapped some of our core tables using FluentNhibernate, wrote some simple LinqToNHibernate queries, religiously followed Test Driven Development and Domain Driven Design until we stumbled across our first major issue.

Queries run by NHibernate were not re-using SQL Server execution plans This was causing us some major performance issues since some queries were taking a few seconds just to generate a plan. We quickly managed to figure out the problem caused viewing the queries using SQL Profiler. NHibernate was passing parameter sizes dynamically based on the length of the value rather than from the mapping which was causing SQL Server to create new execution plans for each unique query.

We found a good explanation and “fix” setting prepare_sql to true in the NHibernate config.

This seemed to fix the parameter size issue but now the queries were being sent using exec sp_prepexec which even had the DBA’s scratching their heads over as it’s documented as a system procedure used to facilitate cursors within SQL Server. The DBAs later informed us that running queries like this causes the execution plans to only be re-used per open connection so for every connection it would still have to create new execution plans.

Carsten Hess wrote a good comment on Ayende’s Blog explaning the issue to which no follow up was made but helped us find and fix the issue. I’ve attached the file for those interested in the fix as to why this isn’t the default behaviour of NHibernate has us perplexed. I've just commenting out an if statement in \Driver\SQLClientDriver.cs found in NHibernate source code thus forcing it to call SetParameterSizes() all the time regardless of the prepare_sql setting alowing us to set it to false so queries are sent normally and excecution plans being issued and re-used correctly.

The whole experience left us feeling weary, had we not discovered the issue beforehand it almost certainly would have brought down our application if we went live with NHibernate. In the end we decided to hold off on implementing the ORM to give it more investigation.

Our journey wasn’t a waste of time as it has brought us to learn about many new skills along the way that has already had an affect on our programming. Test Driven Development, Dependency Injection, Inversion of Control, Domain Driven Design all of which has given us an understanding of some techniques we can use to better develop our system.

Attached: SqlClientDriver.cs

EDIT: Andrei Volkov has posted a good followup in which he explains the history of this issue and an alternative fix to create your own driver. NHibernate parameter sizes controversy

kick it on DotNetKicks.com Shout it



BlogEngine Flaws

clock July 27, 2008 21:46 by author Naz

Get Blog Engine I'm part of the small open source team for dashCommerce an .NET shopping cart system so please don't get me wrong this article isn't about dissing the hard work and time developers have put into BlogEngine it is just to highlight some of the the design flaws I've encountered which we should help to improve on in future versions. I will still continue to use blogengine as it's still the best out there but it can be better...

This site is currently distributed across multiple web servers sometimes referred to as “Cloud Hosting”. Many large popular websites work of this kind of architecture to keep up with demand of resources required to process user requests. I’ve read somewhere Facebook currently has around 200 distributed web servers for hosting their site at various parts of the world.

BlogEngine runs of a singleton caching model where it caches posts and comments into an static object and then reads and writes that object to either an XML or Database when required. A common problem with this design is each server does not have direct access to the in memory object. Due to this when a comment is posted on server 1 gets saved to database, server 2 doesn't know that there has been change so you wont see the update until server 2 updates itself. However there are some work-rounds the simplest is just using the standard .NET caching model instead of singleton caching as you can specify an expiration times and also set-up things like cache dependency enabling your servers can get back to sync.

Recently I’ve been having problems as the site has gotten more popular I’ve had comments and even posts disappearing randomly, sometimes re-appearing you might have experienced this yourself either on my site or in your own so after divulging into the code to see what was happening found something I thought was shocking. When you add a comment, or Rating, Approving and Remove Comments this is what BlogEngine DbBlogProvider actually does...

  1. UPDATE The post
  2. DELETE All Tags for that post
  3. INSERT All Tags for that post
  4. DELETE All Posts Categories
  5. INSERT All Posts Categories
  6. DELETE All existing comments for that post
  7. INSERT All comments back in including the new comment
  8. DELETE All post notifications
  9. INSERT All post notifications


Remember all this when all it needed to do is INSERT into Comments table the new Comment!

From what I can see (I could be wrong) it is doing it without an SqlTransaction so if something where to go wrong it wont rollback changes. This can also cause concurrancy issues say if two people are adding comments at the same time i'm not sure if it will lock it. So instead of just getting delayed updates my web servers are actually in constant battle with each other overwriting each others changes when they save content every time someone post's a comment or rates an article.

I hacked a workaround so Add Comment just does what it needs to by adding new Abstract Methods to BlogProvider but this meant I had to write the same methods for XMLProvider but XML's and relational databases are completely different so I just stubbed them out.

I hope the developers take note about this for future versions there might have been a reason for this the only thing I can think of is they tried to reduce the number of methods a BlogProvider requires.

kick it on DotNetKicks.com



enum to friendly string extension method

clock June 3, 2008 12:05 by author Naz

We use enums quite extensively in our application as they are great for representing integral values in a strongly typed way using symbolic names eg.

if (Status == UserStatus.NotLoggedInAYear)
    ArchiveRecord();


is a lot more clearer and meaningful making it easier to maintain than

if (Status == 3)
    ArchiveRecord()


The enum names are not very friendly to the user and I recently read a some good articles creating user friendly strings for enum values and Enum description values which tried to solve this problem.

I think i've found a better solution to this problem using extension methods.

public enum RemovalType
{
    None,
    ManAndVan,
    FullRemoval,
    FullRemovalsAndPacking
}
 
public static class RemovalTypeEnum
{
    /// <summary>
    /// Returns a friendly enum name
    /// </summary>
    public static string ToFriendlyString(this RemovalType removalType)
    {
        switch (removalType)
        {
            case RemovalType.ManAndVan:
                return "Man & Van Service";
            case RemovalType.FullRemoval:
                return "Standerd removals service";
            case RemovalType.FullRemovalsAndPacking:
                return "Full removals and packing service";
            default:
                return removalType.ToString();
        }
    }
}

 

RemovalType removalType = RemovalType.ManAndVan;
removalType.ToFriendlyString()


This implementation creates an extension method on the actual enum "RemovalType" which then allows you to call a ToFriendlyString() on the instance of all enums of that type I think this a more fluid implementation and also means better performance compared to the other implementations as it doesn't need to use reflection.

You will notive i've decided to leave the default return value to call ToString() on the enum value which means you only need to implement the values that need to be made friendlier.

You can also call it easily inside databinded controls in the aspx page.

<%# ((RemovalType)Eval("ServiceType")).ToFriendlyString() %>



kick it on DotNetKicks.com



We made it to asp.net front page!

clock May 23, 2008 08:00 by author Naz

Daves article on Implementing Generic Caching hit asp.net front page as article of the day for a week!



SCOPE_IDENTITY() return the id from the database on insert

clock May 22, 2008 20:15 by author Naz

As a .NET programmer most of my time is spent coding in C# and I try to avoid writing SQL where possible, which is great as we have dba's that can help with the more complicated queries. Why is it so complicated to write a loop without turning the database upside down? I'm not saying it's not possible it's just the language can me annoying at times.

Anyways, Recently I had to write an insert stored procedure and needed to return the ID of the row I was inserting. While writing my usual bad SQL I came across a fascinating function I’ve never used before, SCOPE_IDENTITY().
Here's short example of how you can use the SCOPE_IDENTITY() function while doing an SQL INSERT to return the identity value of the row just inserted.

In this example I’m inserting a new customer record using a stored procedure and have declared a output parameter which I'd like to return to my application.

CREATE PROCEDURE [dbo].[Customer_Insert]
    @Name VARCHAR(255),
    @Email VARCHAR(255),
    @Phone VARCHAR(255),
    @CustomerID INT OUTPUT
AS
BEGIN
    INSERT INTO dbo.Customer ([Name], Email, Phone)
    VALUES (@Name,@Email,@Phone)
 
    SET @CustomerID = SELECT CustomerID 
              FROM dbo.Customer 
                  WHERE [Name] = @Name 
              AND Email = @Email 
              AND Phone = @Phone
END



What I’ve done wrong here is after inserting run a select to try and SET the @CustomerID. This is a bit risky as it could return more than 1 record, or it return an of completely different record.

SQL's SCOPE_IDENTITY() function can return the last identity value inserted into an identity column in the same scope e.g. a stored procedure, trigger, function, or batch. Alternativly you can also use the @@IDENTITY function to return the last identity value inserted into an identity column regardless of the scope.

Now lets improve my stored procedure using SCOPE_IDENTITY().

CREATE PROCEDURE [dbo].[Customer_Insert]
    @Name VARCHAR(255),
    @Email VARCHAR(255),
    @Phone VARCHAR(255),
    @CustomerID INT OUTPUT
AS
BEGIN
    INSERT INTO dbo.Customer ([Name], Email, Phone)
    VALUES (@Name,@Email,@Phone)
 
    SET @CustomerID = CAST(SCOPE_IDENTITY() AS INT)
END


I've casted the value returned by SCOPE_IDENTITY() to make sure the confirms to the return parametor @CustomerID INT OUTPUT.

kick it on DotNetKicks.com



Why can't you have handlers with multiple paths in web.config?

clock May 6, 2008 17:29 by author Naz

I have created IIS7 asset handler for my application which deals with images and stylesheets by serving them from a CMS database. For some reason the new IIS7 handlers section doesn't allow multiple paths for a handler, so you have to map each path like so..

<handlers>
    <add name="AssetHandlerGif" path="*.gif" verb="GET" type="CMS.AssetHandler" />
    <add name="AssetHandlerJpg" path="*.jpg" verb="GET" type="CMS.AssetHandler" />
    <add name="AssetHandlerPng" path="*.png" verb="GET" type="CMS.AssetHandler" />
    <add name="AssetHandlerCss" path="*.css" verb="GET" type="CMS.AssetHandler" />
<handlers>


This seems a bit odd since with the older httpHandler you were do this in one line

<httpHandlers> 
    <add verb="GET" path="*.jpg,*.gif,*.png,*.css" type="CMS.AssetHandler" validate="false"/>
</httpHandlers>


So can someone tell my why this does not work..am i doing something wrong here?

<handlers>
    <add name="AssetHandler" path="*.jpg,*.gif,*.png,*.css" verb="GET" type="CMS.AssetHandler" />
<handlers>


kick it on DotNetKicks.com



Select Text or Value From DropDownList Extension Method

clock April 25, 2008 17:22 by author Naz

Here is a cool way to select an item from the DropDownList using it's value.

ddlCountries.Items.FindByValue(value).Selected = true;


However I keep forgetting how to do it and end up spending ages searching for it, so here is a very usefull extension method that allows you to select an item from a DropDownList using the text or value of the item without needing to know the index of the item.

using System;
using System.Runtime.Serialization;
using System.Web.UI.WebControls;
 
namespace Core.ExtensionMethods
{
    public class GenericDropDownListException : Exception, ISerializable
    {
        public GenericDropDownListException(string type, string value) : 
            base(string.Format("Unable to set  \"{0}\" to {1}", type, value)) { }
    }
 
    public static class DropDownListExt
    {
        public static void SelectValue(this DropDownList bob, string value)
        {
            try
            {
                if (bob.SelectedIndex >= 0)
                    bob.Items[bob.SelectedIndex].Selected = false;
                bob.Items.FindByValue(value).Selected = true;
            }
            catch
            {
                throw new GenericDropDownListException("value", value);
            }
        }
 
        public static void SelectText(this DropDownList bob, string text)
        {
            try
            {
                if (bob.SelectedIndex >= 0)
                    bob.Items[bob.SelectedIndex].Selected = false;
                bob.Items.FindByText(text).Selected = true;
            }
            catch
            {
                throw new GenericDropDownListException("value", text);
            }
        }
    }
}


Now all you need to do to select an item from the DropDownList is:

ddlCountries.SelectText("UK");


kick it on DotNetKicks.com



To Extension Method

clock April 4, 2008 22:35 by author Naz

Many times you find yourself having to convert the type of an object to another. The ToString() method is probably one of the most useful methods, it's great for easy conversion of objects to string, but what if you want to do it the other way round or even an int to a decimal?

Say I had a string and I wanted it to turn it into an Int32, I could just use the Convert class and do a Convert.ToInt32(myInt) but I would like to be able to do this myInt.ToInt32().

Well now you can with .NET 3.5 Extension Methods! Here's my implementation

public static T To<T>(this IConvertible s)
{
    return (T)Convert.ChangeType(s, typeof(T));
}


All objects that inherit from an IConvertible e.g. string, int, bool etc., will convert the value to the type you specify e.g.

int myInt = myInt.To<Int32>();


It works perfectly with the Visual Studio Intellisense 


kick it on DotNetKicks.com

 


Why am I blogging

clock April 4, 2008 16:47 by author Naz

I've been recently asking myself "Should I blog?" it seemed to me like everyone these days is bloging about one thing or another. I've always felt like contributing but never had the courage to do anything about it until a couple of days ago when I read this interesting blog article.

http://codebetter.com/blogs/jeremy.miller/archive/2008/01/25/should-i-blog.aspx

So I decided to give it a go and here I am today writing my first blog article. I'm not the best of writers and I’m sure I’ll occasionally get things wrong but for me it's all about the experience and the chance to share what I enjoy most, coding.



TextBox


RecentComments

Comment RSS

Sign in