<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" version="2.0">
  <channel>
    <title>Simon Taylor - .Net developer, Cheltenham</title>
    <description>My record of coding problems solved and new things discovered</description>
    <link>http://www.sharpcoder.co.uk/</link>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>BlogEngine.NET 1.6.0.0</generator>
    <language>en-UK</language>
    <blogChannel:blogRoll>http://www.sharpcoder.co.uk/opml.axd</blogChannel:blogRoll>
    <blogChannel:blink>http://www.dotnetblogengine.net/syndication.axd</blogChannel:blink>
    <dc:creator>Simon Taylor</dc:creator>
    <dc:title>Simon Taylor - .Net developer, Cheltenham</dc:title>
    <geo:lat>0.000000</geo:lat>
    <geo:long>0.000000</geo:long>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/sharpcoder" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="sharpcoder" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
      <title>Dear Diary...</title>
      <description>&lt;p&gt;It has been quite a while since my last diary entry and my blog posts have been fairly sparse of late generally. I'm going to try to get back to one a week again moving forward, I've got quite a back log of blog posts built up that I want to get through.&lt;/p&gt;
&lt;p&gt;Business, touch wood, is still going well. I have finished my contract in Bristol and am now working for a startup. The startup has been set up by a contact I have in Canada and it is the most enjoyment I've had out of work in a long time. I've been responsible for requirements capture, functional requirements and of course architecture and development. I'm getting to use lots of cool technologies (for the good of the client not my own enjoyment) such as ASP.NET MVC 4.0 and Windows Azure. I'm working from home which means that I don't have to deal with a long commute which feels like it has improved the quality of my life considerably as well. The only downside I can see right now is that the project is likely to only last a couple of months, certainly initially, and it may be difficult to find another contract that I enjoy working on quite as much!&lt;/p&gt;
&lt;p&gt;The other great thing about this contract/project is that it feels like a step in the right direction towards setting up a consultancy. I'm providing consultancy services to my client rather than making up the numbers in an office somewhere. The chances are my next project will be a regular contract and that's great, but I don't think it's wrong to have ambition and I feel like this project is giving me a taster of what it's like to have my own consultancy (albeit a tiny one) rather than being a contractor - and I like it!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;Lessons Learnt&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There's been a couple of things that I've learnt over the past couple of months. The first one is that contractors don't always get shown Christmas spirit! A couple of weeks before Christmas, myself and the other contractors I was working with in Bristol, found out that they didn't want us in for the two weeks over Christmas and New Year. Supposedly this was meant to be in our contracts but a HR blunder meant that it wasn't. I wasn't particularly happy about this although I wasn't quite as vocal about it as others were. One of the managers made a very good point though which I think is definitely worth remembering - he said that there was bound to be a certain amount of time over the Christmas period that we weren't required and it was our responsibility to find out when that was. It was quite a hard line to take, but he was ultimately 100% correct with what he was saying and we shouldn't have assumed we would just be off between Christmas and New Year and nothing else.&lt;/p&gt;
&lt;p&gt;The second thing I have learnt is that I really need to stop overlapping contracts. I needed to get some work done on the design aspect of my current project ahead of starting on it full time when I finished in Bristol. Working full time, plus a long cummute and then coming home and working evenings and weekends is hard work. I don't mind the hard work so much, but it impacts on my family as well. It's just important that I keep that work/life balance...&lt;/p&gt;</description>
      <link>http://www.sharpcoder.co.uk/post/2012/02/26/Dear-Diary.aspx</link>
      <author>Simon</author>
      <comments>http://www.sharpcoder.co.uk/post/2012/02/26/Dear-Diary.aspx#comment</comments>
      <guid>http://www.sharpcoder.co.uk/post.aspx?id=676da99c-cc43-409e-88c6-3b01ff312f05</guid>
      <pubDate>Sun, 26 Feb 2012 23:07:00 +0100</pubDate>
      <dc:publisher>Simon</dc:publisher>
      <pingback:server>http://www.sharpcoder.co.uk/pingback.axd</pingback:server>
      <pingback:target>http://www.sharpcoder.co.uk/post.aspx?id=676da99c-cc43-409e-88c6-3b01ff312f05</pingback:target>
      <slash:comments>250</slash:comments>
      <trackback:ping>http://www.sharpcoder.co.uk/trackback.axd?id=676da99c-cc43-409e-88c6-3b01ff312f05</trackback:ping>
      <wfw:comment>http://www.sharpcoder.co.uk/post/2012/02/26/Dear-Diary.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.sharpcoder.co.uk/syndication.axd?post=676da99c-cc43-409e-88c6-3b01ff312f05</wfw:commentRss>
    </item>
    <item>
      <title>NHibernate.Caches.AppFabric - Documentation</title>
      <description>&lt;p&gt;NHibernate.Caches.AppFabric is a &lt;a href="http://msdn.microsoft.com/en-us/windowsserver/ee695849" target="_blank"&gt;Windows Server AppFabric&lt;/a&gt; &lt;a href="http://nhforge.org/blogs/nhibernate/archive/2009/02/09/quickly-setting-up-and-using-nhibernate-s-second-level-cache.aspx" target="_blank"&gt;second level cache&lt;/a&gt; provider for &lt;a href="http://nhforge.org/Default.aspx" target="_blank"&gt;NHibernate&lt;/a&gt;. NHibernate.Caches.AppFabric is based on NHibernate.Caches.Velocity which as you can see from &lt;a href="http://stackoverflow.com/questions/3233792/appfabric-could-not-contact-the-cache-service" target="_blank"&gt;my StackOverflow question&lt;/a&gt; is not being actively maintained. I have created a new project rather than editing/updating the existing project firstly because my requests to join the NHibernate project unfortunately weren't answered and also, because of the additional features I have added, it seemed to me like this should be a new project.  I also discovered that &lt;a href="https://nhibernate.jira.com/browse/NHCH-31" target="_blank"&gt;Paul Duran had already tried to add the changes&lt;/a&gt; I described on StackOverflow, but they don't seem to have been added to the main project either. If anyone feels strongly that this code should be added to the main NHibernate project then I will happily consider it.&lt;/p&gt;
&lt;p&gt;The easiest way to get hold of the provider is with &lt;a href="http://nuget.org/packages/NHibernate.Caches.AppFabric" target="_blank"&gt;NuGet&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: mceinline;"&gt;Install-Package NHibernate.Caches.AppFabric&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Alternatively you can &lt;a href="https://github.com/SimonTaylor/NHibernate.Caches.AppFabric" target="_blank"&gt;download the code from GitHub&lt;/a&gt; and build the solution yourself.&lt;/p&gt;
&lt;p&gt;What follows is a description of the features that I have added to NHibernate.Caches.AppFabric and how to configure them. These features are over and above simply implementing the ICacheProvider interface which I won't really go into here&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;AppFabric Configuration&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You will need to add a DataCacheClient section to your web.config to tell the AppFabric client how to connect to AppFabric. Below is a minimal example that uses the default ports. More information on how to configure AppFabric can be found on &lt;a href="http://msdn.microsoft.com/en-us/library/ee790907.aspx" target="_blank"&gt;MSDN&lt;/a&gt;.&lt;/p&gt;
&lt;div class="codebox"&gt;
&lt;pre class="csharpcode"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configSections&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;section&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="dataCacheClient"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="Microsoft.ApplicationServer.Caching.DataCacheClientSection, Microsoft.ApplicationServer.Caching.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"&lt;/span&gt; &lt;span class="attr"&gt;allowLocation&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt; &lt;span class="attr"&gt;allowDefinition&lt;/span&gt;&lt;span class="kwrd"&gt;="Everywhere"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
  ...
  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configSections&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  ...
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;dataCacheClient&lt;/span&gt; &lt;span class="attr"&gt;channelOpenTimeout&lt;/span&gt;&lt;span class="kwrd"&gt;="5"&lt;/span&gt; &lt;span class="attr"&gt;requestTimeout&lt;/span&gt;&lt;span class="kwrd"&gt;="1000"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="rem"&gt;&amp;lt;!-- cache host(s) --&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;hosts&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;host&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="localhost"&lt;/span&gt; &lt;span class="attr"&gt;cachePort&lt;/span&gt;&lt;span class="kwrd"&gt;="22233"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;hosts&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;dataCacheClient&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  ...&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;Example Configuration&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You will need to tell NHibernate to use NHibernate.Caches.AppFabric as the second level cache provider and also switch on second level caching. That is all you &lt;em&gt;need&lt;/em&gt;&amp;nbsp;to do but there are also a number of additional and optional configuration settings. If you install the provider through NuGet, an example configuration similar to the configuration below will be added to your applications app.config/web.config.&lt;/p&gt;
&lt;div class="codebox"&gt;
&lt;pre class="csharpcode"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configSections&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;section&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="AppFabricProviderSettings"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="NHibernate.Caches.AppFabric.AppFabricProviderSettings, NHibernate.Caches.AppFabric"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    ...
  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configSections&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  ...
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;AppFabricProviderSettings&lt;/span&gt; &lt;span class="attr"&gt;CacheType&lt;/span&gt;&lt;span class="kwrd"&gt;="Named"&lt;/span&gt; &lt;span class="attr"&gt;NamedCacheTypeRegionName&lt;/span&gt;&lt;span class="kwrd"&gt;="nhibernate"&lt;/span&gt; &lt;span class="attr"&gt;NamedCachesMustExist&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="attr"&gt;LockTimeout&lt;/span&gt;&lt;span class="kwrd"&gt;="30000"&lt;/span&gt; &lt;span class="attr"&gt;LocksRegionName&lt;/span&gt;&lt;span class="kwrd"&gt;="Locks"&lt;/span&gt; &lt;span class="attr"&gt;SerializationProvider&lt;/span&gt;&lt;span class="kwrd"&gt;="NHibernate.Caches.AppFabric.Tests.Functional.SerializationProvider, NHibernate.Caches.AppFabric.Tests"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
  ...&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Each of the attributes and some that aren't shown above are explained below.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;CacheType&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;At the NHibernate level, either through mappings or when constructing ICriteria queries, you specify the region that the data should be cached. Region in this context is simply the term that NHibernate gives to the bucket that data should be stored in. Through the CacheType setting, the AppFabric provider can be configured to treat the NHibernate region as an AppFabric region (Region)&amp;nbsp;&lt;em&gt;or &lt;/em&gt;an AppFabric named cache (Named). Using regions is slightly simpler to manage, however using named caches allows you to apply different policies for cache expiration etc to each named cache (or NHibernate region). For example, you may store system properties in one named cache which has a very long (maybe 24 hours) time to live set (&lt;a href="http://msdn.microsoft.com/en-us/library/ff718177.aspx"&gt;see MSDN for how to configure this&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&amp;nbsp;&lt;/strong&gt;Another draw back of using regions is that data cannot be distributed across multiple hosts (&lt;a href="http://msdn.microsoft.com/en-us/library/ee790985.aspx"&gt;more info on MSDN&lt;/a&gt;), therefore you don't get the full scalability benefits of the distributed cache. Unfortunately, the current implementation still uses regions even when configured as Named. This is a bug that I will aim to fix as soon as possible although I suspect that for the vast majority of people using this provider, this won't actually be an issue.&lt;/p&gt;
&lt;p&gt;The default value for this property is: Region&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;NamedCacheTypeRegionName&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When using the Named CacheType, data is still stored in a region within the named cache. This setting allows you to configure the name of that region. This setting is ignored if the CacheType is set to Region.&lt;/p&gt;
&lt;p&gt;The default value for this property is: nhibernate&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;RegionCacheTypeCacheName&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This setting is only relevant if the CacheType is set to Region, otherwise it is ignored. This setting allows you to configure the name of the cache that the regions are created in.&lt;/p&gt;
&lt;p&gt;The default value for this property is: nhibernate&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;NamedCachesMustExist&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If the named caches do not exist when the provider attempts to write data to them an exception will be thrown. This setting allows you to configure the provider to catch the exception and use the (AppFabric) default cache instead. If you have CacheType set to Named, this is useful because NHibernate uses some internal regions, for example, for caching queries which you may not have created corresponding named caches for in your cluster. Although the default setting for this property is false, you should be careful leaving it as false as it may mask issues by data being written to the default cache rather than the named cache you expected, it may also impact performance of your application due to exceptions being thrown and caught.&lt;/p&gt;
&lt;p&gt;The default value for this property is: false&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;LockTimeout&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The timeout period in miliseconds for locks.&lt;/p&gt;
&lt;p&gt;The default value for this property is: 30000&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;LocksRegionName&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The provider needs to keep track of locks so that it can release the lock at some point in the future. Because of the distributed nature of the cache and the fact that multiple clients (web servers) could be accessing the cache the provider stores the locks in the distributed cache. This setting allows you to configure the name of the cache that the locks are stored in.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The name of this setting is slightly misleading as the provider stores the locks in a named cache (with the name configured) and as such the named cache should exsist (and will have to if NamedCachesMustExist is set to true).&lt;/p&gt;
&lt;p&gt;The default value for this property is: Locks&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;SerializationProvider&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;By default AppFabric uses xml serialization when storing the data in the cache; this serialization isn't particularly performant. This setting allows you to configure a serialization provider to override the serialization AppFabric uses by default. The serialization provider you configure simply needs to implement the NHibernate.Caches.AppFabric.ISerializationProvider interface.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The objects that NHibernate stores in second-level cache are not the entities that you have mapped in your application, but internal NHibernate wrappers. This may make using a provider based on something like &lt;a href="http://code.google.com/p/protobuf-net/"&gt;protobuf.net&lt;/a&gt;&amp;nbsp;as I originally envisioned, difficult to use. I plan on investigating whether it is even possible as soon as I can.&lt;/p&gt;
&lt;p&gt;The default value for this property is: null&lt;/p&gt;</description>
      <link>http://www.sharpcoder.co.uk/post/2012/01/11/NHibernateCachesAppFabric-Documentation.aspx</link>
      <author>Simon</author>
      <comments>http://www.sharpcoder.co.uk/post/2012/01/11/NHibernateCachesAppFabric-Documentation.aspx#comment</comments>
      <guid>http://www.sharpcoder.co.uk/post.aspx?id=58fcf6ef-4a6d-4520-8a12-44a3741db69b</guid>
      <pubDate>Wed, 11 Jan 2012 13:27:00 +0100</pubDate>
      <dc:publisher>Simon</dc:publisher>
      <pingback:server>http://www.sharpcoder.co.uk/pingback.axd</pingback:server>
      <pingback:target>http://www.sharpcoder.co.uk/post.aspx?id=58fcf6ef-4a6d-4520-8a12-44a3741db69b</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.sharpcoder.co.uk/trackback.axd?id=58fcf6ef-4a6d-4520-8a12-44a3741db69b</trackback:ping>
      <wfw:comment>http://www.sharpcoder.co.uk/post/2012/01/11/NHibernateCachesAppFabric-Documentation.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.sharpcoder.co.uk/syndication.axd?post=58fcf6ef-4a6d-4520-8a12-44a3741db69b</wfw:commentRss>
    </item>
    <item>
      <title>NHibernate.Caches.AppFabric</title>
      <description>&lt;p&gt;I have created an NHibernate second-level cache provider for AppFabric. For more information on why I have created this project please take a look at the &lt;a href="http://stackoverflow.com/questions/3233792/appfabric-could-not-contact-the-cache-service" target="_blank"&gt;Stack Overflow question&lt;/a&gt; I posted some 18 months ago. You can find all of the &lt;a href="https://github.com/SimonTaylor/NHibernate.Caches.AppFabric" target="_blank"&gt;code on GitHub&lt;/a&gt; and in the coming days I am planning on creating a NuGet package for this project and fully documenting all the features either here or on GitHub, and detailing some of the features I plan to add in the future as well as adding some (more) tests. &lt;/p&gt;
&lt;p&gt;I would describe this as a beta version currently, I am happy to support anyone who wants to use it but ultimately it is used at your own risk. I would appreciate any feedback including bugs and additional features.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update: &lt;/strong&gt;You can now install this with NuGet. The name of the package is &lt;a title="NuGet Gallery" href="http://nuget.org/packages/NHibernate.Caches.AppFabric" target="_blank"&gt;NHibernate.Caches.AppFabric&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update: &lt;/strong&gt;I have documented all of the provider features &lt;a title="Documentation" href="http://www.sharpcoder.co.uk/post/2012/01/11/NHibernateCachesAppFabric-Documentation.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt;</description>
      <link>http://www.sharpcoder.co.uk/post/2012/01/04/NHibernateCachesAppFabric.aspx</link>
      <author>Simon</author>
      <comments>http://www.sharpcoder.co.uk/post/2012/01/04/NHibernateCachesAppFabric.aspx#comment</comments>
      <guid>http://www.sharpcoder.co.uk/post.aspx?id=200ac7c1-907f-48d4-8db0-42e851a19da7</guid>
      <pubDate>Wed, 04 Jan 2012 17:52:00 +0100</pubDate>
      <dc:publisher>Simon</dc:publisher>
      <pingback:server>http://www.sharpcoder.co.uk/pingback.axd</pingback:server>
      <pingback:target>http://www.sharpcoder.co.uk/post.aspx?id=200ac7c1-907f-48d4-8db0-42e851a19da7</pingback:target>
      <slash:comments>43</slash:comments>
      <trackback:ping>http://www.sharpcoder.co.uk/trackback.axd?id=200ac7c1-907f-48d4-8db0-42e851a19da7</trackback:ping>
      <wfw:comment>http://www.sharpcoder.co.uk/post/2012/01/04/NHibernateCachesAppFabric.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.sharpcoder.co.uk/syndication.axd?post=200ac7c1-907f-48d4-8db0-42e851a19da7</wfw:commentRss>
    </item>
    <item>
      <title>Effective mentoring</title>
      <description>&lt;p&gt;I have had various team lead and senior developer positions that have involved mentoring other developers. I think the most difficult part of mentoring is when a new developer joins an existing project.  There will undoubtedly be a lot of knowledge that has been built up over the course of the project that, no matter how good your processes are, will be in exisiting team members heads rather than on a wiki or some other shared document somewhere. My approach in the past (which is true of most people's I believe) is to spend a few hours going over the project structure pointing out key features of the framework or libraries etc and then letting the new dev start developing, making ones self available to answer any questions as he comes up with them. You can try to get the new developer started by looking at bug fixing rather than a new development task in an attempt to flatten out the learning curve, but ultimately I think the approach is flawed. Personally, I am happy to go off and dig around code and work things out for myself. I have found a lot of developers get intimidated by that though. I don't think that is necessarily a true reflection of whether they are a good developer or not. I think it is just some peoples personality, that when faced with a daunting task (which this can be to many) that they panic, shutdown and end up spinning their wheels not really getting to grips with the project or code base etc, let alone any new concepts they are being introduced to for the first time.&lt;/p&gt;
&lt;p&gt;Recently I was listening to &lt;a title="Java Pose" href="http://javaposse.com/webpage/java-posse-359-roundup-11-developer-practices" target="_blank"&gt;Java Pose episode #359 - "Roundup '11 - Developer Practices"&lt;/a&gt; and I had an epitomy! Of course there is a better way of mentoring/bringing new developers on to a project. The solution in my opinion is pair programming. Well not exactly pair programming in the agile/xp sense as it is meant to be peers that program in pairs, but sitting down in front of a computer, maybe letting the newbie drive and working through a development task (or tasks) together. I think that only by taking this approach can you effectively start to pass on the knowledge a new team member really needs to get up to speed on the project quickly. As you work through a problem together you will come across things that you need to mention that you would never have covered in a 2/3 hour overview. Similarly the newbie will get to see how you approach the problem as well as your thought processes and how a certain problem should be approached within the boundaries of the current project. You will be able to get immediate feedback of what the new guy is finding difficult and what they aren't and since you're sat next to them they won't end up spending days trying to figure out trivial problems.&lt;/p&gt;
&lt;p&gt;How long this pair programming should last is dependent upon the level of the new developer as well as the complexity of the problem. Maybe a few hours will still be enough for an experienced lead developer to get up to speed, but I don't think it is a problem if you are still doing it after a week. A junior developer is likely to require more time and if that is the case then maybe multiple members of the team can take time to pair with them. I think it is fair to say that if the new guy still requires this level of support after his three month probationary period then it's probably time for them to go&amp;nbsp;&lt;img title="Wink" src="http://www.sharpcoder.co.uk/editors/tiny_mce3/plugins/emotions/img/smiley-wink.gif" border="0" alt="Wink" /&gt;&lt;/p&gt;</description>
      <link>http://www.sharpcoder.co.uk/post/2011/12/08/Effective-mentoring.aspx</link>
      <author>Simon</author>
      <comments>http://www.sharpcoder.co.uk/post/2011/12/08/Effective-mentoring.aspx#comment</comments>
      <guid>http://www.sharpcoder.co.uk/post.aspx?id=21a74fe8-fa51-4bf9-8dc9-70ae49bdf378</guid>
      <pubDate>Thu, 08 Dec 2011 13:14:00 +0100</pubDate>
      <dc:publisher>Simon</dc:publisher>
      <pingback:server>http://www.sharpcoder.co.uk/pingback.axd</pingback:server>
      <pingback:target>http://www.sharpcoder.co.uk/post.aspx?id=21a74fe8-fa51-4bf9-8dc9-70ae49bdf378</pingback:target>
      <slash:comments>80</slash:comments>
      <trackback:ping>http://www.sharpcoder.co.uk/trackback.axd?id=21a74fe8-fa51-4bf9-8dc9-70ae49bdf378</trackback:ping>
      <wfw:comment>http://www.sharpcoder.co.uk/post/2011/12/08/Effective-mentoring.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.sharpcoder.co.uk/syndication.axd?post=21a74fe8-fa51-4bf9-8dc9-70ae49bdf378</wfw:commentRss>
    </item>
    <item>
      <title>Reading from the database with NHibernate</title>
      <description>&lt;p&gt;When reading data from the database with NHibernate, there are now more options than ever. It is my opinion that some of these options are better than others and that they should be used in the following order of preference. &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Wherever possible the methods available to us on the session object should be used ahead of anything else.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;Session.Get&amp;lt;Cat&amp;gt;(1);&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If we need to do anything more complex than reading by Id or getting all records from a table then we have to construct a where clause somehow. NHibernate 3 has brought with it &lt;a href="" target="_blank"&gt;Linq to NHibernate&lt;/a&gt; which allows you to construct queries such as:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;var cat = (from c &lt;span class="kwrd"&gt;in&lt;/span&gt; Session.Query&amp;lt;Cat&amp;gt;()
           &lt;span class="kwrd"&gt;where&lt;/span&gt; c.Name == &lt;span class="str"&gt;"Fluffy"&lt;/span&gt;
           select c).SingleOrDefault();&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There are a number of scenarios that are not well suited to Linq to NHibernate. Consider a search screen where the user enters search criteria which results in clauses &lt;em&gt;only&lt;/em&gt; being added to the 'where' part of the query where the user has selected a value - in other words it is built up at runtime. In this case you must use the &lt;a href="http://nhforge.org/blogs/nhibernate/archive/2009/12/17/queryover-in-nh-3-0.aspx" target="_blank"&gt;query over api&lt;/a&gt;.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;
var cat =
    Session.QueryOver&amp;lt;Cat&amp;gt;()
        .Where(c =&amp;gt; c.Name == &lt;span class="str"&gt;"Fluffy"&lt;/span&gt;)
        .SingleOrDefault();&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;li&gt;
&lt;p&gt;The query over API is built on top of the criteria API. I don't know for sure, but there may well be some functionality not supported by the query over API in which case you may be forced to use the criteria API instead - I have never come across a scenario however.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;
var cat = Session.CreateCriteria&amp;lt;Cat&amp;gt;()
    .Add(Restrictions.Eq(&lt;span class="str"&gt;"Name"&lt;/span&gt;, &lt;span class="str"&gt;"Fluffy"&lt;/span&gt;))
    .UniqueResult&amp;lt;Cat&amp;gt;();&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The magic strings here play havoc with refactoring however, which is why the crieria API is so far down my list.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Some complex queries aren't possible to construct with the criteria or query over API's in which case your only choice is to use HQL (unless you want to use an SP or native SQL instead). In my experience these scenarios are few and far between. HQL is one big magic string and therefore suffers from the same refactoring problems as the criteria API. If you use it, you must have a strong suite of unit (or maybe more accurately, integration) tests backing it. I would suggest however, that if you really can't construct your query using anything other than HQL you probably have a design issue and maybe an ORM such as NHibernate or even a relational database isn't the right choice in this circumstance.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;
var cat = Session.CreateQuery(&lt;span class="str"&gt;"from Cat c where c.Name = :name"&lt;/span&gt;)
                 .SetString(&lt;span class="str"&gt;"name"&lt;/span&gt;, &lt;span class="str"&gt;"Fluffy"&lt;/span&gt;)
                 .UniqueResult&amp;lt;Cat&amp;gt;();&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <link>http://www.sharpcoder.co.uk/post/2011/11/30/Reading-from-the-database-with-NHibernate.aspx</link>
      <author>Simon</author>
      <comments>http://www.sharpcoder.co.uk/post/2011/11/30/Reading-from-the-database-with-NHibernate.aspx#comment</comments>
      <guid>http://www.sharpcoder.co.uk/post.aspx?id=241f87cc-0422-47c4-85d1-476cdb56d96d</guid>
      <pubDate>Wed, 30 Nov 2011 13:31:00 +0100</pubDate>
      <dc:publisher>Simon</dc:publisher>
      <pingback:server>http://www.sharpcoder.co.uk/pingback.axd</pingback:server>
      <pingback:target>http://www.sharpcoder.co.uk/post.aspx?id=241f87cc-0422-47c4-85d1-476cdb56d96d</pingback:target>
      <slash:comments>34</slash:comments>
      <trackback:ping>http://www.sharpcoder.co.uk/trackback.axd?id=241f87cc-0422-47c4-85d1-476cdb56d96d</trackback:ping>
      <wfw:comment>http://www.sharpcoder.co.uk/post/2011/11/30/Reading-from-the-database-with-NHibernate.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.sharpcoder.co.uk/syndication.axd?post=241f87cc-0422-47c4-85d1-476cdb56d96d</wfw:commentRss>
    </item>
    <item>
      <title>Dear Diary...</title>
      <description>&lt;p&gt;It has been about a month since my first "diary" entry about starting my own business, so this seemed like a good time to write my second. &lt;/p&gt;
&lt;p&gt;I have spent the majority of the month working on my first 'real' contract. I say 'real' not because I want to be disrespectful, but because my first full-time contract was working for &lt;a href="http://www.triggersoft.com" target="_blank"&gt;Trigger Software&lt;/a&gt;&amp;nbsp;who I worked for before moving to Canada to work for &lt;a href="http://www.infusion.com" target="_blank"&gt;Infusion&lt;/a&gt;. It was a nice gentle introduction to contracting as it was in familiar surroundings and I was working with many of the old faces that were there when I left. The project was a great opportunity to add WPF to my CV (even if it may or may not be dead) and an opportunity I probably wouldn't have got had they not already known me. Ultimately, Trigger would have liked me to have continued on the project however, by the time they approached me about extending my contract I had already agreed to start a new contract in Bristol. I do feel a little guilty about this as I should maybe have approached Trigger before agreeing to the new contract; on the other hand I couldn't risk missing out on a new contract on the off-chance that Trigger may have offered me an extension. I have continued to help out Trigger when and where I can, so although I could have maybe handled things a little differently, I think we are still on good terms and will continue to be able to work together in the future.&lt;/p&gt;
&lt;p&gt;My new contract in Bristol is going OK. I don't really feel as though I have been as productive as I would have liked, but this is due in part to the technical direction of the project not really being 100% clear, to anyone on the project not just me. I think we are now begining to find that direction and we will soon be able to concentrate on solving some of the interesting and complex technical challenges that we have to solve. I have also never really worked in an environment that wasn't solely interested in churning out software. I'm sat in an office with the accounts team and the MD which is situated next to a reasonably sized sales team, so I'm getting to see a completely different business/industry in action which is quite interesting. The one downside to the contract is that it's (depending on traffic) a 1.25 hour commute away from Cheltenham. In the past I've always shyed away from commuting but as a contractor it's probably something I need to get used to. Bristol seems to be an up and coming area of the country in terms of technology and the chances are there are going to be more contracting opportunities in the Bristol area compared with Cheletenham.&lt;/p&gt;
&lt;p&gt;I don't actually mind the actual commute, it does unfortunately reduce the amount of time I get to spend with my wife and daughter in the week, but the main thing is that I'm absolutely shattered! The last thing I really want to do is work when I get home in the evening. This has also given me a valuable business lesson - my business at the moment isn't scalable! It's just me! I have already mentioned that I have helped out Trigger after starting in Bristol and that is something that they would be happy for me to continue doing. Unfortunately, I have had to push back on the Trigger work, purely because I am too tired to commit to working every evening and at weekends as well. I still do bits and pieces for Infusion and as someone just trying to get a business off the ground in a trying economic climate it seems crazy to turn down work, but there is only so much work - in addition to the dirving - that I'm physically capable of doing. My product ideas have taken a total back seat at the moment and I really want to get them started, this is really the only way I can see that I can actually scale my business, by generating enough income to finance expanding my consultancy business.&lt;/p&gt;
&lt;p&gt;Having said all that, I have managed to find time to start an open source project. It is very early days so far, but I think I can get something reasonably feature complete in a couple of weeks, assuming I'm not too wiped out from driving to Bristol and back each day. As soon as I'm at that point I will do a blog post about it.&lt;/p&gt;</description>
      <link>http://www.sharpcoder.co.uk/post/2011/11/23/Dear-Diary.aspx</link>
      <author>Simon</author>
      <comments>http://www.sharpcoder.co.uk/post/2011/11/23/Dear-Diary.aspx#comment</comments>
      <guid>http://www.sharpcoder.co.uk/post.aspx?id=0faa12c7-7fbb-4ed4-bdf5-6fe7d5ccae93</guid>
      <pubDate>Wed, 23 Nov 2011 13:06:00 +0100</pubDate>
      <dc:publisher>Simon</dc:publisher>
      <pingback:server>http://www.sharpcoder.co.uk/pingback.axd</pingback:server>
      <pingback:target>http://www.sharpcoder.co.uk/post.aspx?id=0faa12c7-7fbb-4ed4-bdf5-6fe7d5ccae93</pingback:target>
      <slash:comments>139</slash:comments>
      <trackback:ping>http://www.sharpcoder.co.uk/trackback.axd?id=0faa12c7-7fbb-4ed4-bdf5-6fe7d5ccae93</trackback:ping>
      <wfw:comment>http://www.sharpcoder.co.uk/post/2011/11/23/Dear-Diary.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.sharpcoder.co.uk/syndication.axd?post=0faa12c7-7fbb-4ed4-bdf5-6fe7d5ccae93</wfw:commentRss>
    </item>
    <item>
      <title>The Non-Generic Generic Pattern</title>
      <description>&lt;p&gt;From time to time I've needed to use generic classes but haven't known what the generic arguments are until runtime - for example because I'm iterating over classes I've found through reflection or I've read from a database. Hopefully, the contrived example below will explain what I mean. &lt;/p&gt;
&lt;p&gt;Imagine I have the three entity classes below, which all implement the &lt;em&gt;IEntity &lt;/em&gt;interface and can be read with the &lt;em&gt;Repository &lt;/em&gt;class.&lt;/p&gt;
&lt;div class="codebox"&gt;&lt;pre class="csharpcode"&gt;
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; IEntity
{
    &lt;span class="kwrd"&gt;int&lt;/span&gt; Id { get; set; }
}

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Customer : IEntity
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Id { get; set; }
}

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Product : IEntity
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Id { get; set; }
}

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Supplier : IEntity
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Id { get; set; }
}

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Repository&amp;lt;TEntity&amp;gt; &lt;span class="kwrd"&gt;where&lt;/span&gt; TEntity : IEntity, &lt;span class="kwrd"&gt;new&lt;/span&gt;()
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; TEntity Get(&lt;span class="kwrd"&gt;int&lt;/span&gt; id)
    {
        &lt;span class="rem"&gt;// A real application would get the data from a database or something&lt;/span&gt;
        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; TEntity()
        {
            Id = id
        };
    }
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Lets now say I wanted to read an instance of each of these items, possibly to display to the user. I said this example was contrived! A more realistic scenario maybe a generic administrative tool that allows a user to select a type of entity to view and gives them the chance to enter the Id of the entity to view, but I wanted to keep things simple.&lt;/p&gt;
&lt;p&gt;The following Linq query will get me all of the different types of entity, but how can we use the generic &lt;em&gt;Repository&lt;/em&gt;&amp;nbsp;class to read them?&lt;/p&gt;
&lt;div class="codebox"&gt;&lt;pre class="csharpcode"&gt;
    IEnumerable&amp;lt;Type&amp;gt; entityTypes =
        from t &lt;span class="kwrd"&gt;in&lt;/span&gt; Assembly.GetAssembly(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(IEntity)).GetTypes()
        &lt;span class="kwrd"&gt;where&lt;/span&gt; &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(IEntity).IsAssignableFrom(t) &amp;amp;&amp;amp; t.IsClass
        select t;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;What we would like to do is something like the following, which is invalid C#&lt;/p&gt;
&lt;div class="codebox"&gt;&lt;pre class="csharpcode"&gt;
    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Type entityType &lt;span class="kwrd"&gt;in&lt;/span&gt; entityTypes)
    {
        var repository = &lt;span class="kwrd"&gt;new&lt;/span&gt; Repository&amp;lt;entityType&amp;gt;()
        ...
    }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;My solution is to create a private inner class which implements a private inner interface.&lt;/p&gt;
&lt;div class="codebox"&gt;&lt;pre class="csharpcode"&gt;
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; IInnerRepository
    {
        IEntity Get(&lt;span class="kwrd"&gt;int&lt;/span&gt; id);
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; InnerRepository&amp;lt;TEntity&amp;gt; : IInnerRepository &lt;span class="kwrd"&gt;where&lt;/span&gt; TEntity : IEntity, &lt;span class="kwrd"&gt;new&lt;/span&gt;()
    {
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; Repository&amp;lt;TEntity&amp;gt; _repository;

        &lt;span class="kwrd"&gt;public&lt;/span&gt; InnerRepository()
        {
            _repository = &lt;span class="kwrd"&gt;new&lt;/span&gt; Repository&amp;lt;TEntity&amp;gt;();
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; IEntity Get(&lt;span class="kwrd"&gt;int&lt;/span&gt; id)
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; _repository.Get(id);
        }
    }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;We can then create a generic type passing in the type of entity we are dealing with and then create an instance of that generic class with the &lt;em&gt;Activator&lt;/em&gt;&amp;nbsp;class.&lt;/p&gt;
&lt;div class="codebox"&gt;&lt;pre class="csharpcode"&gt;
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IEntity LoadEntity(Type type, &lt;span class="kwrd"&gt;int&lt;/span&gt; id)
    {
        &lt;span class="rem"&gt;// Check that type is valid as a generic argument&lt;/span&gt;
        Type genericType = &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(InnerRepository&amp;lt;&amp;gt;).MakeGenericType(type);
        IInnerRepository repository = (IInnerRepository)Activator.CreateInstance(genericType);

        &lt;span class="kwrd"&gt;return&lt;/span&gt; repository.Get(id);
    }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;This makes for what I believe is quite an elegant solution to a recurring problem with generics. The majority of the code is type safe and can be checked by the compiler. There is a small amount of reflection but it is again fairly self contained and could iteslef be wrapped up in a static utility or extension method. This solution is probably slightly overkill for the above example as ultimately you could just create an instance of &lt;em&gt;Repository&lt;/em&gt;&amp;nbsp;rather than &lt;em&gt;InnerRepository&lt;/em&gt;, but if there were more generic calls or classes to use, hopefully you can see the benefits of encapsulating them in an inner class like this.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.sharpcoder.co.uk/file.axd?file=2011%2f11%2fSharpcoder.NonGenericGenerics.zip"&gt;Download an example solution (34.35 kb)&lt;/a&gt;&lt;/p&gt;</description>
      <link>http://www.sharpcoder.co.uk/post/2011/11/16/The-Non-Generic-Generic-Pattern.aspx</link>
      <author>Simon</author>
      <comments>http://www.sharpcoder.co.uk/post/2011/11/16/The-Non-Generic-Generic-Pattern.aspx#comment</comments>
      <guid>http://www.sharpcoder.co.uk/post.aspx?id=86c87128-52e9-49c2-854c-207ff6038925</guid>
      <pubDate>Wed, 16 Nov 2011 13:52:00 +0100</pubDate>
      <dc:publisher>Simon</dc:publisher>
      <pingback:server>http://www.sharpcoder.co.uk/pingback.axd</pingback:server>
      <pingback:target>http://www.sharpcoder.co.uk/post.aspx?id=86c87128-52e9-49c2-854c-207ff6038925</pingback:target>
      <slash:comments>256</slash:comments>
      <trackback:ping>http://www.sharpcoder.co.uk/trackback.axd?id=86c87128-52e9-49c2-854c-207ff6038925</trackback:ping>
      <wfw:comment>http://www.sharpcoder.co.uk/post/2011/11/16/The-Non-Generic-Generic-Pattern.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.sharpcoder.co.uk/syndication.axd?post=86c87128-52e9-49c2-854c-207ff6038925</wfw:commentRss>
    </item>
    <item>
      <title>Random Useful SQL Queries</title>
      <description>&lt;p&gt;What follows are a number of useful SQL queries I have needed and am bound to forget if I don't make a note of them. I'll aim to add to this list as and when I come up against other non-trivial queries I'm bound to forget. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Query all locks on a database&lt;/strong&gt;&lt;/p&gt;
&lt;div class="codebox"&gt;&lt;pre class="csharpcode"&gt;
&lt;span class="kwrd"&gt;SELECT&lt;/span&gt;  L.request_session_id &lt;span class="kwrd"&gt;AS&lt;/span&gt; SPID,
        DB_NAME(L.resource_database_id) &lt;span class="kwrd"&gt;AS&lt;/span&gt; DatabaseName,
        O.Name &lt;span class="kwrd"&gt;AS&lt;/span&gt; LockedObjectName,
        P.object_id &lt;span class="kwrd"&gt;AS&lt;/span&gt; LockedObjectId,
        L.resource_type &lt;span class="kwrd"&gt;AS&lt;/span&gt; LockedResource,
        L.request_mode &lt;span class="kwrd"&gt;AS&lt;/span&gt; LockType,
        ST.text &lt;span class="kwrd"&gt;AS&lt;/span&gt; SqlStatementText,       
        ES.login_name &lt;span class="kwrd"&gt;AS&lt;/span&gt; LoginName,
        ES.host_name &lt;span class="kwrd"&gt;AS&lt;/span&gt; HostName,
        TST.is_user_transaction &lt;span class="kwrd"&gt;as&lt;/span&gt; IsUserTransaction,
        &lt;span class="kwrd"&gt;AT&lt;/span&gt;.name &lt;span class="kwrd"&gt;as&lt;/span&gt; TransactionName,
        CN.auth_scheme &lt;span class="kwrd"&gt;as&lt;/span&gt; AuthenticationMethod
&lt;span class="kwrd"&gt;FROM&lt;/span&gt;    sys.dm_tran_locks L
        &lt;span class="kwrd"&gt;JOIN&lt;/span&gt; sys.partitions P &lt;span class="kwrd"&gt;ON&lt;/span&gt; P.hobt_id = L.resource_associated_entity_id
        &lt;span class="kwrd"&gt;JOIN&lt;/span&gt; sys.objects O &lt;span class="kwrd"&gt;ON&lt;/span&gt; O.object_id = P.object_id
        &lt;span class="kwrd"&gt;JOIN&lt;/span&gt; sys.dm_exec_sessions ES &lt;span class="kwrd"&gt;ON&lt;/span&gt; ES.session_id = L.request_session_id
        &lt;span class="kwrd"&gt;JOIN&lt;/span&gt; sys.dm_tran_session_transactions TST &lt;span class="kwrd"&gt;ON&lt;/span&gt; ES.session_id = TST.session_id
        &lt;span class="kwrd"&gt;JOIN&lt;/span&gt; sys.dm_tran_active_transactions &lt;span class="kwrd"&gt;AT&lt;/span&gt; &lt;span class="kwrd"&gt;ON&lt;/span&gt; TST.transaction_id = &lt;span class="kwrd"&gt;AT&lt;/span&gt;.transaction_id
        &lt;span class="kwrd"&gt;JOIN&lt;/span&gt; sys.dm_exec_connections CN &lt;span class="kwrd"&gt;ON&lt;/span&gt; CN.session_id = ES.session_id
        &lt;span class="kwrd"&gt;CROSS&lt;/span&gt; APPLY sys.dm_exec_sql_text(CN.most_recent_sql_handle) &lt;span class="kwrd"&gt;AS&lt;/span&gt; ST
&lt;span class="kwrd"&gt;WHERE&lt;/span&gt;   resource_database_id = db_id()
&lt;span class="kwrd"&gt;ORDER&lt;/span&gt; &lt;span class="kwrd"&gt;BY&lt;/span&gt; L.request_session_id&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Count per hour&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So imagaine you wanted to get the number of sales per hour, since a certain date.&lt;/p&gt;
&lt;div class="codebox"&gt;&lt;pre class="csharpcode"&gt;
&lt;span class="kwrd"&gt;SELECT&lt;/span&gt;
  DATEADD(&lt;span class="kwrd"&gt;HOUR&lt;/span&gt;, DATEDIFF(&lt;span class="kwrd"&gt;HOUR&lt;/span&gt;, 0, pr.&lt;span class="kwrd"&gt;Date&lt;/span&gt;), 0),
  p.Description,
  &lt;span class="kwrd"&gt;COUNT&lt;/span&gt;(*)
&lt;span class="kwrd"&gt;FROM&lt;/span&gt;
  PurchaseRecord pr
    &lt;span class="kwrd"&gt;INNER&lt;/span&gt; &lt;span class="kwrd"&gt;JOIN&lt;/span&gt; Product p &lt;span class="kwrd"&gt;ON&lt;/span&gt;
      p.Id = pr.ProductId
&lt;span class="kwrd"&gt;WHERE&lt;/span&gt;
  pr.&lt;span class="kwrd"&gt;Date&lt;/span&gt; &amp;gt; &lt;span class="str"&gt;'2011-11-08 23:59:59.999'&lt;/span&gt;
&lt;span class="kwrd"&gt;GROUP&lt;/span&gt; &lt;span class="kwrd"&gt;BY&lt;/span&gt;
  DATEADD(&lt;span class="kwrd"&gt;HOUR&lt;/span&gt;, DATEDIFF(&lt;span class="kwrd"&gt;HOUR&lt;/span&gt;, 0, pr.&lt;span class="kwrd"&gt;Date&lt;/span&gt;), 0),
  p.Description 
&lt;span class="kwrd"&gt;ORDER&lt;/span&gt; &lt;span class="kwrd"&gt;BY&lt;/span&gt;
  DATEADD(&lt;span class="kwrd"&gt;HOUR&lt;/span&gt;, DATEDIFF(&lt;span class="kwrd"&gt;HOUR&lt;/span&gt;, 0, pr.&lt;span class="kwrd"&gt;Date&lt;/span&gt;), 0)&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Diagram component installation issue&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In the past I have had problems trying to install the MS-SQL diagram component, in order to generate schema diagrams. The following query has helped in the past.&lt;/p&gt;
&lt;div class="codebox"&gt;&lt;pre class="csharpcode"&gt;
&lt;span class="kwrd"&gt;EXEC&lt;/span&gt; sp_dbcmptlevel &lt;span class="str"&gt;'TestDatabase'&lt;/span&gt;, &lt;span class="str"&gt;'90'&lt;/span&gt;;
&lt;span class="kwrd"&gt;go&lt;/span&gt;
&lt;span class="kwrd"&gt;ALTER&lt;/span&gt; &lt;span class="kwrd"&gt;AUTHORIZATION&lt;/span&gt; &lt;span class="kwrd"&gt;ON&lt;/span&gt; &lt;span class="kwrd"&gt;DATABASE&lt;/span&gt;::TestDatabase &lt;span class="kwrd"&gt;TO&lt;/span&gt; "sa"
&lt;span class="kwrd"&gt;go&lt;/span&gt;
&lt;span class="kwrd"&gt;use&lt;/span&gt; [TestDatabase]
&lt;span class="kwrd"&gt;go&lt;/span&gt;
&lt;span class="kwrd"&gt;EXECUTE&lt;/span&gt; &lt;span class="kwrd"&gt;AS&lt;/span&gt; &lt;span class="kwrd"&gt;USER&lt;/span&gt; = N&lt;span class="str"&gt;'dbo'&lt;/span&gt; REVERT
Go&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;</description>
      <link>http://www.sharpcoder.co.uk/post/2011/11/09/Random-Useful-SQL-Queries.aspx</link>
      <author>Simon</author>
      <comments>http://www.sharpcoder.co.uk/post/2011/11/09/Random-Useful-SQL-Queries.aspx#comment</comments>
      <guid>http://www.sharpcoder.co.uk/post.aspx?id=85e810cc-934b-45c0-9b8d-bb42429a15c1</guid>
      <pubDate>Wed, 09 Nov 2011 13:40:00 +0100</pubDate>
      <dc:publisher>Simon</dc:publisher>
      <pingback:server>http://www.sharpcoder.co.uk/pingback.axd</pingback:server>
      <pingback:target>http://www.sharpcoder.co.uk/post.aspx?id=85e810cc-934b-45c0-9b8d-bb42429a15c1</pingback:target>
      <slash:comments>27</slash:comments>
      <trackback:ping>http://www.sharpcoder.co.uk/trackback.axd?id=85e810cc-934b-45c0-9b8d-bb42429a15c1</trackback:ping>
      <wfw:comment>http://www.sharpcoder.co.uk/post/2011/11/09/Random-Useful-SQL-Queries.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.sharpcoder.co.uk/syndication.axd?post=85e810cc-934b-45c0-9b8d-bb42429a15c1</wfw:commentRss>
    </item>
    <item>
      <title>Get-CacheHost</title>
      <description>&lt;p&gt;When dealing with AppFabric, I regularly want to check the status of the nodes in my AppFabric cluster. Generally all I want is the results presented after a (Re-)Start of the cache cluster. &lt;/p&gt;
&lt;p&gt;There is a simple powershell cmdlet that does this without having to restart the cluster, but I contiunually forget what it is and where to find it in the &lt;a href="http://msdn.microsoft.com/en-us/library/ff921010.aspx"&gt;MSDN documentation&lt;/a&gt;, so I'm recording it here so that I can get back to it quickly. The cmdlet is Get-CacheHost and the results can be seen below:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.sharpcoder.co.uk/image.axd?picture=2011%2f11%2fGet-CacheHost.png" alt="" /&gt;&lt;/p&gt;</description>
      <link>http://www.sharpcoder.co.uk/post/2011/11/02/Get-CacheHost.aspx</link>
      <author>Simon</author>
      <comments>http://www.sharpcoder.co.uk/post/2011/11/02/Get-CacheHost.aspx#comment</comments>
      <guid>http://www.sharpcoder.co.uk/post.aspx?id=39a64a19-ae14-4868-909b-076f37997617</guid>
      <pubDate>Wed, 02 Nov 2011 12:58:00 +0100</pubDate>
      <dc:publisher>Simon</dc:publisher>
      <pingback:server>http://www.sharpcoder.co.uk/pingback.axd</pingback:server>
      <pingback:target>http://www.sharpcoder.co.uk/post.aspx?id=39a64a19-ae14-4868-909b-076f37997617</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.sharpcoder.co.uk/trackback.axd?id=39a64a19-ae14-4868-909b-076f37997617</trackback:ping>
      <wfw:comment>http://www.sharpcoder.co.uk/post/2011/11/02/Get-CacheHost.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.sharpcoder.co.uk/syndication.axd?post=39a64a19-ae14-4868-909b-076f37997617</wfw:commentRss>
    </item>
    <item>
      <title>Starting blogging and your own business</title>
      <description>&lt;p&gt;This blog has never really been updated as often as I would have liked it to have been. I am determined to put that right going forward! After talking about it for years I have finally left the safety of full-time employment and have set up my own business: SPT Development Ltd. This is part of the reason why I am more determined than ever to start blogging more regularly. From the limited amount of blogging I have done up untill now I have already discovered that it is a fantastic way of marketing yourself. I have also been inspired by &lt;a title="hanselminutes" href="http://hanselminutes.com/" target="_blank"&gt;Scott Hanselman's recent series on start-up's&lt;/a&gt;&amp;nbsp;and as well as blogging about technical subjects, I also thought it would be good to document the experiences I have as a start-up. I make no promises but I have set myself a target of blogging about something every week and I will probably try to blog about my start-up experiences once a month.&lt;/p&gt;
&lt;p&gt;I am currently contracting but the plan is not to still be contracting in 10 years time. Ideally I would like to be retired by then &lt;img title="Smile" src="http://www.sharpcoder.co.uk/editors/tiny_mce3/plugins/emotions/img/smiley-smile.gif" border="0" alt="Smile" /&gt;, but failing that I would like to have grown SPT Development Ltd into something more than just a one man show. I have a number of product ideas that I am planning on working on and would like the contracting work to turn into a consultancy at some point down the road. Finally, I keep saying to myself things like "I will have to learn from that experience..." and "In the future I will..." then before I know it I have forgotten what those lesson's were, so to remind myself and help others I hope to document those things here as well - where they are things I can talk openly about anyway&amp;nbsp;&lt;img title="Smile" src="http://www.sharpcoder.co.uk/editors/tiny_mce3/plugins/emotions/img/smiley-smile.gif" border="0" alt="Smile" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;First Diary Entry&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I have been contracting now for two months and so far I am happy that I have made the right decision. Fortunately, I stayed on very good terms with my two previous employers and am currently contracting part-time for my previous employer and full-time for the employer before that. The main lesson I have learnt so far is not to burn any bridges&amp;nbsp;&lt;img title="Wink" src="http://www.sharpcoder.co.uk/editors/tiny_mce3/plugins/emotions/img/smiley-wink.gif" border="0" alt="Wink" /&gt;&amp;nbsp;Next week I start a new three month contract which came through another previous aquaintance. I am learning that as a contractor and presumably as an entrepreneur in general, it is important to tell as many people as possible what you are doing as you never know where that next opportunity may come from.&lt;/p&gt;
&lt;p&gt;Although it is early days and I am enjoying contracting I am still attempting to put things in place to grow my business. As already mentioned, I have a number of product ideas, but they are fairly fuzzy still and I really need to spend the time making those ideas more concrete and choosing one that I can really get my teeth into. Some of my ideas could make really good open source projects and if I go with one of them, I will definitely be talking about them more on here. The one problem I have in this area is that I have a young family that I &lt;em&gt;won't&lt;/em&gt;&amp;nbsp;neglect so finding the time to work on products outside of normal business hours when I'm contracting, is proving difficult. I would like to earn enough money contracting to be able to take some time off and work on my products, but even if this does happen I think I really need to have made a start on them outside of normal office hours. I'm not adverse to working long hours but there are more important things in life than making money.&lt;/p&gt;
&lt;p&gt;Finally, I have also done some quotes for some project work. So far this has not exactly been successful! The first one I did although the prospective client was initially positive, the lead went cold and despite chasing I haven't heard anything since. The second one was effectively freelance work for an ex-colleague who has set up his own successful consultancy. Unfortunately my quote was more than twice what they were expecting to pay. Maybe I could shaved some time off my estimates and I added contingency on, but since they insisted on a fixed price this seems only sensible to me - I have seen the opposite in action. Ultimately, I think their time-estimates were unrealistic and I would be interested to learn what happened on that project. Although it was dissapointing not to win the quote I am happy that I didn't under sell myself and that I fully expect that if someone undertakes the work with a quote closer to what they were hoping for, they will either be quoting based on a rate lower than I would be prepared to work for or they will be working very long hours! I was told I would be kept in mind for future projects, so fingers crossed I will be.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;Hope This Helps&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One thing I have found starting out in contracting is that other contractors play their cards pretty close to their chests. It is sometimes difficult to know where to start with contracting and certainly how to go about setting up your own business. Here's a few things that I can think of that I have done or needed to do to get started in contracting.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Decide on the type of business you wish to set up - Ltd company (in the UK), sole trader etc. I took no advice and went with a Ltd company. As I understood it and I have since had this confirmed by an accountant, this is in many ways the most tax efficient way of running a company. I believe accountants do however charge more for doing your annual returns etc however.&lt;/li&gt;
&lt;li&gt;Come up with a company name. This is easier said than done!&lt;/li&gt;
&lt;li&gt;Check that the domain for your company exists. Embarrasingly I didn't do this before I registered my first company with companies house. When I did check I found that it was in use and somebody was already (presumably illegally) trading with the company name I had just registered. I was therefore forced to wind that company up and register a new one - enter SPT Development Ltd.&lt;/li&gt;
&lt;li&gt;Register the company with companies house (in the UK).&lt;/li&gt;
&lt;li&gt;Buy the domain. I am the proud owner of www.spt-development.com - I am yet to set up a site however. I have had negative comments about the '-' in the domain. Ultimately I'm happy with it though as in my opinion sptdevelopment looks a mess!&lt;/li&gt;
&lt;li&gt;Decide on a rate. This was something else I found a little difficult not least because other contractors (me included) don't want to tell you what they are charging. In the end I found a few national averages and looked at postings on job websites and went from there. Nobody has tried to haggle with me on my price so far, so that may suggest I'm selling myself short, but I'm earning enough to feed and clothe myself and my family, so I'm fairly happy with that&amp;nbsp;&lt;img title="Smile" src="http://www.sharpcoder.co.uk/editors/tiny_mce3/plugins/emotions/img/smiley-smile.gif" border="0" alt="Smile" /&gt;&lt;/li&gt;
&lt;li&gt;Get a contract. Generally speaking you won't be able to get a contract unless you can tell prospective clients that you are available straight away. I was lucky and found one before I had finished in my full-time position. I've been lucky with my second one as well, that was sorted a couple of weeks before the end of my first contract. Ultimately, what I think I have done well is to tell anyone who will listen that I am contracting. Hopefully, my luck will continue!&lt;/li&gt;
&lt;li&gt;At this point you may need to give your clients a contract to sign. So far I haven't needed to do that as the clients have provided the contract. If I do need to do that in the future I will probably just use one of the ones I have been asked to sign.&lt;/li&gt;
&lt;li&gt;Get an accountant. Somebody once told me that the best way to find a solicitor is to go on recommendations. Rightly or wrongly I put accountants in the same bracket - hopefully that doesn't offend accountants or solicitors&amp;nbsp;&lt;img title="Smile" src="http://www.sharpcoder.co.uk/editors/tiny_mce3/plugins/emotions/img/smiley-smile.gif" border="0" alt="Smile" /&gt;&amp;nbsp;I spoke to a few friends who gave me some recommendations and I went with one of those recomendations. In the UK at least, it is only chartered accountants who can submit your annual return - certainly for a limited company anyway. The hope though is that although this service will cost around a &amp;pound;1000 they will save me at least that in tax savings. From the advice I have been given so far even if my business turns over what I was earning in a full-time position, I will be better off due to the tax breaks I will get.&lt;/li&gt;
&lt;li&gt;If you believe your turnover will exceed the &lt;a href="http://www.hmrc.gov.uk/vat/start/register/when-to-register.htm#2" target="_blank"&gt;current VAT threshold&lt;/a&gt; then get VAT registered (in the UK) as soon as possible. Although you aren't required to do this until you reach that threshold, personally, I think it looks more professional to clients if you charge VAT and ultimately as businesses themselves (in most cases), it isn't really costing them anything extra. It also allows you to claim back the VAT on that new laptop you bought&amp;nbsp;&lt;img title="Smile" src="http://www.sharpcoder.co.uk/editors/tiny_mce3/plugins/emotions/img/smiley-smile.gif" border="0" alt="Smile" /&gt;. The easiest way to do this is &lt;a href="http://www.hmrc.gov.uk/vat/start/register/when-to-register.htm#2" target="_blank"&gt;online&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;One of the least obvious things that you will need to do and your accountant can do this for you is register for PAYE (in the UK). To be able to do this however, you need to register as an employer - even if you are the only employee, as a director you are an employee and your business is the employer. The easiest way to do this is &lt;a href="http://www.hmrc.gov.uk/vat/start/register/when-to-register.htm#2" target="_blank"&gt;online&lt;/a&gt;&amp;nbsp;as well.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am trying to be helpful with this list so if anything is inaccurate, I apologise but accept no responsibility for the consequences. If you see anything that is inaccurate or can think of anything that is missing however, then please let me know and I will add or change it.&lt;/p&gt;</description>
      <link>http://www.sharpcoder.co.uk/post/2011/10/21/Starting-blogging-and-your-own-business.aspx</link>
      <author>Simon</author>
      <comments>http://www.sharpcoder.co.uk/post/2011/10/21/Starting-blogging-and-your-own-business.aspx#comment</comments>
      <guid>http://www.sharpcoder.co.uk/post.aspx?id=cbaeb357-d035-46a4-aaba-c9235216221c</guid>
      <pubDate>Fri, 21 Oct 2011 13:28:00 +0100</pubDate>
      <dc:publisher>Simon</dc:publisher>
      <pingback:server>http://www.sharpcoder.co.uk/pingback.axd</pingback:server>
      <pingback:target>http://www.sharpcoder.co.uk/post.aspx?id=cbaeb357-d035-46a4-aaba-c9235216221c</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.sharpcoder.co.uk/trackback.axd?id=cbaeb357-d035-46a4-aaba-c9235216221c</trackback:ping>
      <wfw:comment>http://www.sharpcoder.co.uk/post/2011/10/21/Starting-blogging-and-your-own-business.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.sharpcoder.co.uk/syndication.axd?post=cbaeb357-d035-46a4-aaba-c9235216221c</wfw:commentRss>
    </item>
  </channel>
</rss>

