<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>LiveMike</title><link>http://www.goatly.net:80/</link><description>LiveMike</description><item><title>Using DynaCache with Unity</title><link>http://www.goatly.net:80/using-dynacache-with-unity</link><description>&lt;p&gt;I’ve had a couple of people ask for concrete examples of using DynaCache with frameworks other than Ninject. The first one that I’ve put together is for Unity.&lt;/p&gt; &lt;p&gt;You’ll find the Unity example in the DynaCache documentation &lt;a href="http://dynacache.codeplex.com/wikipage?title=Example%20using%20Unity" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;</description><pubDate>Sat, 18 May 2013 11:35:38 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/using-dynacache-with-unity</guid></item><item><title>StoryboardCompletedTrigger and SetPropertyAction</title><link>http://www.goatly.net:80/storyboardcompletedtrigger-and-setpropertyaction</link><description>&lt;p&gt;I’ve spent a couple of hours on WinRTTriggers tonight and added a couple of features that have been requested recently, StoryboardCompletedTrigger and SetPropertyAction.&lt;/p&gt; &lt;h2&gt;StoryboardCompletedTrigger &lt;/h2&gt; &lt;p&gt;This trigger allows to to fire an action when a storyboard completes – you can use it like this:&lt;/p&gt;&lt;pre class="xml"&gt;&amp;lt;Triggers:StoryboardCompletedTrigger Storyboard="{StaticResource FlashNameChanged}"&amp;gt;
    &amp;lt;!-- insert your action(s) here --&amp;gt;
&amp;lt;/Triggers:StoryboardCompletedTrigger&amp;gt;
&lt;/pre&gt;
&lt;h2&gt;SetPropertyAction&lt;/h2&gt;
&lt;p&gt;This allows you to react to a trigger by setting a property on an object – most likely your view model:&lt;/p&gt;&lt;pre class="xml"&gt;&amp;lt;Triggers:Interactions.Triggers&amp;gt;
    &amp;lt;Triggers:PropertyChangedTrigger Binding="{Binding Person.Name}"&amp;gt;
        &amp;lt;Triggers:SetPropertyAction Target="{Binding}" 
                                    PropertyName="HasChangedName" Value="true" /&amp;gt;
    &amp;lt;/Triggers:PropertyChangedTrigger&amp;gt;
&amp;lt;/Triggers:Interactions.Triggers&amp;gt;
&lt;/pre&gt;
&lt;p&gt;There’s nothing stopping you binding the new value to something another property on your view model, either:&lt;/p&gt;&lt;pre class="xml"&gt;&amp;lt;Triggers:Interactions.Triggers&amp;gt;
    &amp;lt;Triggers:PropertyChangedTrigger Binding="{Binding Person.Name}"&amp;gt;
        &amp;lt;Triggers:SetPropertyAction Target="{Binding}" 
                          PropertyName="ChangeCount" 
                          Value="{Binding NextChangeCount}" /&amp;gt;
    &amp;lt;/Triggers:PropertyChangedTrigger&amp;gt;
&amp;lt;/Triggers:Interactions.Triggers&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Of course you can combine these with all the other triggers and actions in the WinRTTriggers library in a variety of ways – hopefully these plug a couple of gaps that people have needed filled!&lt;/p&gt;
&lt;p&gt;Hope this helps - I’m always interested in hearing how you get on with using WinRTTriggers in your Windows 8 applications!&lt;/p&gt;</description><pubDate>Thu, 21 Mar 2013 20:31:59 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/storyboardcompletedtrigger-and-setpropertyaction</guid></item><item><title>Async and await in constructors</title><link>http://www.goatly.net:80/async-and-await-in-constructors</link><description>&lt;p&gt;I was working on &lt;a href="http://lifti.codeplex.com/" target="_blank"&gt;LIFTI&lt;/a&gt; last night, trying to create a Windows Store compatible version of it and encountered 2 main problems:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;No support for &lt;a href="http://msdn.microsoft.com/en-us/library/system.transactions.ienlistmentnotification.aspx" target="_blank"&gt;IEnlistmentNotification&lt;/a&gt;, so no transactional support is possible, at least in the same way – I need to do a bit more digging to rule it out completely.  &lt;li&gt;The file management class needed to initialise the backing file during construction. This proved to be a little challenging because all of the WinRT APIs for file management are asynchronous, and don’t &lt;a href="http://stackoverflow.com/questions/8145479/can-constructors-be-async" target="_blank"&gt;mix particularly well with constructors&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The rest of this post will cover how I got around this without re-architecting the code extensively.&lt;/p&gt; &lt;h3&gt;Moving to the WinRT world&lt;/h3&gt; &lt;p&gt;The long and short of what the constructor does is create a read/write stream to the backing file – in the classic .NET world this is really simple:&lt;/p&gt;&lt;pre class="code"&gt;var fileInfo = new FileInfo(filePath);
this.DataStream = fileInfo.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
&lt;/pre&gt;
&lt;p&gt;My initial “cheeky” attempt at getting this working with the WinRT APIs was something along the lines of:&lt;/p&gt;&lt;pre class="code"&gt;var localFolder = ApplicationData.Current.LocalFolder;
var file =  localFolder.CreateFileAsync(&lt;br&gt;    filePath, &lt;br&gt;    CreationCollisionOption.OpenIfExists).&lt;strong&gt;GetResults()&lt;/strong&gt;;
this.DataStream = file.OpenStreamForWriteAsync().&lt;strong&gt;Result&lt;/strong&gt;;&lt;/pre&gt;
&lt;p&gt;Which attempted to bypass the asynchronous nature of the APIs by reading the results inline and forcing the calls to execute synchronously. I didn’t really expect it to work, and sure enough it blew up at runtime – the &lt;em&gt;CreateFileAsync&lt;/em&gt; line threw:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A method was called at an unexpected time. (Exception from HRESULT: 0x8000000E)&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;So the methods really do need to be awaited. But constructors can’t be async, so I ended up kicking off a new Task that ran an async delegate:&lt;/p&gt;&lt;pre class="code"&gt;protected FileManagerBase(string fileName)
{
    Task.Run(
        async () =&amp;gt;
        {
            var localFolder = ApplicationData.Current.LocalFolder;
            var file = await localFolder.CreateFileAsync(
                fileName, 
                CreationCollisionOption.OpenIfExists);
            this.DataStream = await file.OpenStreamForWriteAsync();
        }).Wait();
}
&lt;/pre&gt;
&lt;p&gt;Which seems to work, but I’d be really interested in hearing if this is frowned upon (other than the obvious “you’re blocking the calling thread”) and if there’s a better way of solving the problem.&lt;/p&gt;</description><pubDate>Thu, 07 Mar 2013 22:32:00 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/async-and-await-in-constructors</guid></item><item><title>Aliens vs Finger</title><link>http://www.goatly.net:80/aliens-vs-finger</link><description>&lt;p&gt;I've been working on another game for Windows Phone (7.5+) and the result is &lt;a href="http://www.windowsphone.com/en-gb/store/app/aliens-vs-finger/02a04b4b-f284-4a6e-a424-33bc25763cc2"&gt;Aliens vs Finger&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;&lt;img width="485" height="291" title="6. MainMenu" style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" alt="6. MainMenu" src="http://www.goatly.net/Media/Default/Windows-Live-Writer/Aliens-vs-Finger_10A9F/6.%20MainMenu_c8552d67-fd44-4227-adcb-223a9ef04d07.png" border="0" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img width="485" height="291" title="1. Game1" style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" alt="1. Game1" src="http://www.goatly.net/Media/Default/Windows-Live-Writer/Aliens-vs-Finger_10A9F/1.%20Game1_766c17a2-fb1f-4854-9882-b7b509e52b94.png" border="0" /&gt;&lt;/p&gt;
&lt;p&gt;Aliens vs Finger is a (hopefully!) fun tap-'em-up game where you have to squish the aliens and stop the meteors crossing the screen, all the while being careful to not hit the friendly spacemen. Although it's in the market place as a paid app (the lowest price possible!) - the entire game is available as an ad-supported trial, so you've got nothing to lose by giving it a go - only purchase if you enjoy it!&lt;/p&gt;
&lt;p&gt;For those interested, some of the technical details are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Developed in XNA - I used this for two reasons:
&lt;ul&gt;
&lt;li&gt;Silverlight probably wasn't going to cut it what I was aiming to achieve and I've experimented with XNA before - nothing fancy but I had an appreciation for what I was letting myself in for.&lt;/li&gt;
&lt;li&gt;I wanted to reach the broadest market possible - focusing solely on Windows Phone 8 would have limited that - XNA was the best match for Windows Phone 7.5+.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The high score tables are stored in Azure Mobile Services. As I &lt;a href="http://www.goatly.net/using-azure-mobile-services-from-windows-phone-7-apps"&gt;mentioned previously&lt;/a&gt;, I used the &lt;a href="https://github.com/kenegozi/azure-mobile-csharp-sdk"&gt;azure-mobile-csharp-sdk&lt;/a&gt;to access the API. There are some interesting points about how I managed the data there, and I'll probably write more about that in a separate post.&lt;/li&gt;
&lt;li&gt;All of the animations from the way that the main menu slides around to the way individual aliens move are based around &lt;a href="http://www.robertpenner.com/easing/"&gt;easing functions&lt;/a&gt;. I used a heavily customised version of &lt;a href="http://xnatweener.codeplex.com/"&gt;XNATweener&lt;/a&gt;to manage this.&lt;/li&gt;
&lt;li&gt;The graphics are all drawn by me; I'm no designer, but I'm fairly happy with the results!&lt;/li&gt;
&lt;li&gt;In total I think I spent about one and a half weeks working on it, but as it was one of many "free time" projects it was more like 4 months elapsed time.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you do play it, let me know what you think!&lt;/p&gt;</description><pubDate>Mon, 25 Feb 2013 19:09:00 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/aliens-vs-finger</guid></item><item><title>Using Azure Mobile Services from Windows Phone 7 apps</title><link>http://www.goatly.net:80/using-azure-mobile-services-from-windows-phone-7-apps</link><description>&lt;p&gt;&lt;a href="http://www.windowsazure.com/en-us/develop/mobile/"&gt;Azure Mobile Services&lt;/a&gt; is an pretty cool platform that I&amp;rsquo;ve only just started trying out. Microsoft provide quick jumpstart projects for Windows Store, Windows Phone 8 and iOS apps &amp;ndash; but that&amp;rsquo;s it. If you&amp;rsquo;re like me and are stuck working on a &amp;ldquo;legacy&amp;rdquo; app such as the Windows Phone 7 game that I&amp;rsquo;ve been working on for a couple of weeks now, then you&amp;rsquo;re largely on your own.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re in the same situation, I would recommend that you check out the &lt;a href="https://github.com/kenegozi/azure-mobile-csharp-sdk"&gt;azure-mobile-csharp-sdk&lt;/a&gt; project by &lt;a href="https://github.com/kenegozi"&gt;Ken Egozi&lt;/a&gt;. It seems to do everything I need &amp;ndash; at the moment just querying and inserting - right off the bat, and it looks like the Mono guys have even taken to using this code in the Mono framework, so that&amp;rsquo;s a good sign as well!&lt;/p&gt;
&lt;p&gt;Great job, Ken!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;UPDATE - 14 March 2013&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As good as&amp;nbsp;Ken's library is, check this out: &lt;a href="http://www.johanlaanstra.nl/?p=217"&gt;http://www.johanlaanstra.nl/?p=217&lt;/a&gt;. I've not used it yet myself, but if I was starting from scratch I probably would. I'd be interested to hear people's experiences with it.&lt;/p&gt;</description><pubDate>Sat, 10 Nov 2012 16:04:00 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/using-azure-mobile-services-from-windows-phone-7-apps</guid></item><item><title>Using WinRTTriggers within data templates</title><link>http://www.goatly.net:80/using-winrttriggers-within-data-templates</link><description>&lt;p&gt;&lt;a href="/triggers-in-winrt-xaml#comments"&gt;Kaki104 recently commented&lt;/a&gt; that they were having a problem using triggers in a certain situation. Helpfully a simple repro was provided – a simple grid view, with an attempt to start a storyboard when an item is clicked:&lt;/p&gt; &lt;p&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://www.goatly.net/Media/Default/Windows-Live-Writer/ab3082f74259_A766/image_3.png" width="517" height="291"&gt;&lt;/p&gt; &lt;p&gt;The trigger had been placed within the data template of the item:&lt;/p&gt;&lt;pre class="xml"&gt;&amp;lt;DataTemplate x:Key="DataTemplate1"&amp;gt;
    &amp;lt;Grid HorizontalAlignment="Left" Width="250" Height="250"&amp;gt;
        &amp;lt;Grid.Resources&amp;gt;
            &amp;lt;Storyboard x:Key="storyboard1"&amp;gt;
                &amp;lt;ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" Storyboard.TargetName="border"&amp;gt;
                    &amp;lt;EasingColorKeyFrame KeyTime="0" Value="#FFB8B5B5"/&amp;gt;
                    &amp;lt;EasingColorKeyFrame KeyTime="0:0:1" Value="#FF3C3B3B"/&amp;gt;
                &amp;lt;/ColorAnimationUsingKeyFrames&amp;gt;
                &amp;lt;ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="stackPanel"&amp;gt;
                    &amp;lt;EasingColorKeyFrame KeyTime="0" Value="#A69C5151"/&amp;gt;
                    &amp;lt;EasingColorKeyFrame KeyTime="0:0:1" Value="#A6F9F3F3"/&amp;gt;
                &amp;lt;/ColorAnimationUsingKeyFrames&amp;gt;
            &amp;lt;/Storyboard&amp;gt;
        &amp;lt;/Grid.Resources&amp;gt;

        &amp;lt;t:Interactions.Triggers&amp;gt;
            &amp;lt;t:PropertyChangedTrigger Binding="{Binding Title}"&amp;gt;
                &amp;lt;t:ControlStoryboardAction Action="Start" Storyboard="{StaticResource storyboard1}"/&amp;gt;
            &amp;lt;/t:PropertyChangedTrigger&amp;gt;
        &amp;lt;/t:Interactions.Triggers&amp;gt;

        &amp;lt;Border x:Name="border" Background="#FF3D3D3D"/&amp;gt;
        &amp;lt;StackPanel x:Name="stackPanel" VerticalAlignment="Bottom" Background="#A6000000"&amp;gt;
            &amp;lt;TextBlock Text="{Binding Title}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="60" Margin="15,0,15,0" LayoutUpdated="TextBlock_LayoutUpdated_1" SelectionChanged="TextBlock_SelectionChanged_1"/&amp;gt;
            &amp;lt;TextBlock Text="{Binding Subtitle}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/&amp;gt;
        &amp;lt;/StackPanel&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/DataTemplate&amp;gt;&lt;/pre&gt;
&lt;p&gt;Interestingly the designer complains that there is an “illegal qualified name character” in the XAML, but when you run the code, everything works as expected. &lt;/p&gt;
&lt;p&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://www.goatly.net/Media/Default/Windows-Live-Writer/ab3082f74259_A766/image_2d24f464-d558-4608-8bcc-4cf23df0dc24.png" width="398" height="167"&gt;&lt;/p&gt;
&lt;p&gt;Now, I’ve dug around a little and haven’t been able to work out why this is – debugging the host Visual Studio instance doesn’t reveal any exceptions being thrown, so I can only assume the parser is misreporting a problem, though in my experience it’s usually something I’m doing that’s wrong. If anyone can reveal what that is, I’d be very grateful!&lt;/p&gt;
&lt;p&gt;A simple workaround for this is to just move the contents of the grid into a separate UserControl and reference that from within the DataTemplate instead:&lt;/p&gt;&lt;pre class="xml"&gt;&amp;lt;DataTemplate x:Key="DataTemplate1"&amp;gt;
    &amp;lt;local:ItemUserControl /&amp;gt;
&amp;lt;/DataTemplate&amp;gt;&lt;/pre&gt;
&lt;p&gt;This way you don’t get designer errors and everything works at run time.&lt;/p&gt;
&lt;p&gt;I’ve uploaded the &lt;a href="/Media/Default/Samples/DataTemplateWinRTSample.zip"&gt;sample code for this here&lt;/a&gt;, if you’re interested.&lt;/p&gt;</description><pubDate>Sat, 03 Nov 2012 13:14:12 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/using-winrttriggers-within-data-templates</guid></item><item><title>Using LiveDataScript</title><link>http://www.goatly.net:80/using-livedatascript</link><description>&lt;p&gt;&lt;a href="http://www.goatly.net/downloads/livedatascript" target="_blank"&gt;LiveDataScript&lt;/a&gt; is a little utility to generate SQL insert scripts from SQL Server databases. I wrote it quite a few years ago, but since it’s still fairly useful and the last place it was hosted has now gone the way of the Dodo, I’ve re-hosted it &lt;a href="http://www.goatly.net/downloads/livedatascript" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;This post will cover the high-level basics of using the application.&lt;/p&gt; &lt;h2&gt;Getting started&lt;/h2&gt; &lt;p&gt;After starting LiveDataScript you’ll be prompted to select the server to connect to:&lt;/p&gt; &lt;p&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://www.goatly.net/Media/Default/Windows-Live-Writer/Using-LiveDataScript_D665/image_9039348c-b48b-4540-9d5b-d9f2c4e24909.png" width="387" height="185"&gt;&lt;/p&gt;  &lt;p&gt;As you can see, you can use Windows authentication or SQL Server authentication to connect, depending on which is most appropriate for your server.&lt;/p&gt; &lt;p&gt;Once you’re connected you’ll be able to drill into the databases available on the server in the Server Explorer pane:&lt;/p&gt; &lt;p&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://www.goatly.net/Media/Default/Windows-Live-Writer/Using-LiveDataScript_D665/image_46e95ce8-5a02-4965-b9f8-4d671edc574b.png" width="295" height="215"&gt;&lt;/p&gt; &lt;p&gt;Double clicking on a table will open it up in a new window:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.goatly.net/Media/Default/Windows-Live-Writer/Using-LiveDataScript_D665/image_7.png" target="_blank"&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://www.goatly.net/Media/Default/Windows-Live-Writer/Using-LiveDataScript_D665/image_thumb.png" width="640" height="455"&gt;&lt;/a&gt;&lt;/p&gt;   &lt;h2&gt;Scripting data from a table&lt;/h2&gt; &lt;h3&gt;Scripting all the data&lt;/h3&gt; &lt;p&gt;You have a couple of options here:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Select a table in the Server Explorer and press the Script Tables button (&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://www.goatly.net/Media/Default/Windows-Live-Writer/Using-LiveDataScript_D665/image_4068c484-ff2e-417e-8a4e-a42de9b23291.png" width="107" height="20"&gt;)&lt;/li&gt; &lt;li&gt;Open a table by double-clicking on it and press the Script Window Results button (&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://www.goatly.net/Media/Default/Windows-Live-Writer/Using-LiveDataScript_D665/image_dcd7957b-8977-4e2e-bfb2-e8ab5ed91b40.png" width="155" height="21"&gt;)&lt;/li&gt;&lt;/ol&gt;    &lt;p&gt;Note that each of the buttons has a little dropdown associated to it, giving you a choice of where you want to script to, either to a new window, a file or to the clipboard:&lt;/p&gt; &lt;p&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://www.goatly.net/Media/Default/Windows-Live-Writer/Using-LiveDataScript_D665/image_9ff29d4a-e060-4d6a-83ae-db2f95211208.png" width="164" height="99"&gt;&lt;/p&gt; &lt;h3&gt;Scripting a subset of data&lt;/h3&gt; &lt;p&gt;Again, a couple of options:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Open a table and change the SELECT statement to include a “TOP x” statement, e.g. SELECT TOP 100. Click Refresh Results (or press F5) and then Script Window Results.&lt;/li&gt; &lt;li&gt;Open a table and highlight the rows that you want to script out, then press Script Selected Rows (&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://www.goatly.net/Media/Default/Windows-Live-Writer/Using-LiveDataScript_D665/image_9ce12f32-944a-475c-acc2-7481bda5a57b.png" width="144" height="20"&gt;)&lt;/li&gt;&lt;/ol&gt;  &lt;h3&gt;Selecting the columns to script&lt;/h3&gt; &lt;p&gt;You can always change the columns that should be scripted out by altering the SELECT statement, but there is an easier way using the “Script Column Filters” panel:&lt;/p&gt; &lt;p&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="http://www.goatly.net/Media/Default/Windows-Live-Writer/Using-LiveDataScript_D665/image_6499085d-74d1-448d-96f3-8c094a15051f.png" width="215" height="132"&gt;&lt;/p&gt; &lt;p&gt;By simply unselecting columns in this list and scripting the results, you will remove those columns from the resulting output.&lt;/p&gt; &lt;h2&gt;Summary&lt;/h2&gt; &lt;p&gt;That pretty much covers the basics – I’ll write another post soon covering some of the more advanced ways that you can generate scripts.&lt;/p&gt;</description><pubDate>Sat, 13 Oct 2012 12:50:47 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/using-livedatascript</guid></item><item><title>Conditional trigger actions with WinRTTriggers</title><link>http://www.goatly.net:80/conditional-trigger-actions-with-winrttriggers</link><description>&lt;blockquote&gt; &lt;p&gt;WinRTTriggers is a available from the &lt;a href="http://winrttriggers.codeplex.com/" target="_blank"&gt;codeplex project site&lt;/a&gt; or from &lt;a href="https://nuget.org/packages/WinRTTriggers" target="_blank"&gt;nuget&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt; &lt;p&gt;Sample code for this post can be &lt;a href="http://www.goatly.net/Media/Default/Samples/ConditionalActionSample.zip" target="_blank"&gt;downloaded here&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The latest update to WinRTTriggers (v1.1.0) includes 2 big changes:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Multiple actions can be specified against a trigger  &lt;li&gt;An action can have conditions associated to it&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The first point is fairly self explanatory, but the second deserves a bit more elaboration.&lt;/p&gt; &lt;p&gt;Take the situation where on the first use of your application you want to introduce the user to certain features using a storyboard animation. In the view model you might have some flag to indicate “first use”:&lt;/p&gt;&lt;pre class="code"&gt;public class SampleViewModel : ViewModelBase
{
    private bool isFirstUse;

    public bool IsFirstUse
    {
        get { return this.isFirstUse; }
        set
        {
            if (this.isFirstUse != value)
            {
                this.isFirstUse = value;
                this.OnPropertyChanged();
            }
        }
    }
}&lt;/pre&gt;
&lt;p&gt;In your page, you include the view model as a resource and databind it to the page:&lt;/p&gt;&lt;pre class="html"&gt;&amp;lt;Page
    x:Class="ConditionalActionSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ConditionalActionSample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:Triggers="using:WinRT.Triggers"&amp;gt;
    
    &amp;lt;Page.Resources&amp;gt;
        &amp;lt;local:SampleViewModel x:Name="ViewModel"&amp;gt;
            &amp;lt;local:SampleViewModel.IsFirstUse&amp;gt;True&amp;lt;/local:SampleViewModel.IsFirstUse&amp;gt;
        &amp;lt;/local:SampleViewModel&amp;gt;
    &amp;lt;/Page.Resources&amp;gt;
    
    &amp;lt;Page.DataContext&amp;gt;
        &amp;lt;Binding Source="{StaticResource ViewModel}" /&amp;gt;
    &amp;lt;/Page.DataContext&amp;gt;&lt;/pre&gt;
&lt;p&gt;The content of the page is really simple – just a “magic” button and some introductory text that is initially hidden by setting the opacity to 0:&lt;/p&gt;&lt;pre class="html"&gt;    &amp;lt;Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"&amp;gt;
        &amp;lt;Button x:Name="magicButton" Content="Click for magic..." /&amp;gt;
        &amp;lt;Border x:Name="border" Opacity="0" CornerRadius="500" BorderThickness="3" Background="#FF9FB292" BorderBrush="#FF162314" Margin="152,239,-510,239" Padding="20,0,478,0" RenderTransformOrigin="0.5,0.5"&amp;gt;
            &amp;lt;TextBlock FontSize="34.667" TextWrapping="Wrap" Foreground="#FF266C05" TextAlignment="Center" VerticalAlignment="Center" Text="This button is magic. Clicking it performs all sorts of wonderous actions." /&amp;gt;
        &amp;lt;/Border&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/Page&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Next up, there’s a storyboard that just flashes the introductory text:&lt;/p&gt;&lt;pre class="html"&gt;    &amp;lt;Page.Resources&amp;gt;
        &amp;lt;local:SampleViewModel x:Name="ViewModel"&amp;gt;
            &amp;lt;local:SampleViewModel.IsFirstUse&amp;gt;True&amp;lt;/local:SampleViewModel.IsFirstUse&amp;gt;
        &amp;lt;/local:SampleViewModel&amp;gt;
&lt;font style="background-color: #ffff00"&gt;        &amp;lt;Storyboard x:Name="FirstLoadStoryboard"&amp;gt;
            &amp;lt;DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="border"&amp;gt;
                &amp;lt;EasingDoubleKeyFrame KeyTime="0:0:1" Value="0"/&amp;gt;
                &amp;lt;EasingDoubleKeyFrame KeyTime="0:0:2" Value="1" &amp;gt;
                	&amp;lt;EasingDoubleKeyFrame.EasingFunction&amp;gt;
                		&amp;lt;BounceEase Bounces="1"/&amp;gt;
                	&amp;lt;/EasingDoubleKeyFrame.EasingFunction&amp;gt;
                &amp;lt;/EasingDoubleKeyFrame&amp;gt;
            &amp;lt;/DoubleAnimationUsingKeyFrames&amp;gt;
        &amp;lt;/Storyboard&amp;gt;&lt;/font&gt;
    &amp;lt;/Page.Resources&amp;gt;

&lt;/pre&gt;
&lt;p&gt;And finally, the bit that ties it all together, the triggers on the page:&lt;/p&gt;&lt;pre class="html"&gt;    &amp;lt;Triggers:Interactions.Triggers&amp;gt;
        &amp;lt;Triggers:EventTrigger EventName="Loaded"&amp;gt;
            &amp;lt;Triggers:ControlStoryboardAction Storyboard="{StaticResource FirstLoadStoryboard}" Action="Start"&amp;gt;
                &amp;lt;Triggers:Condition LeftOperand="{Binding IsFirstUse}" Operator="Equals" RightOperand="True" /&amp;gt;
            &amp;lt;/Triggers:ControlStoryboardAction&amp;gt;
        &amp;lt;/Triggers:EventTrigger&amp;gt;
    &amp;lt;/Triggers:Interactions.Triggers&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Notice that the Condition element within the ControlStoryboardAction element instructs that it should only fire when the IsFirstUse property equals “True”.&lt;/p&gt;
&lt;p&gt;Running the code in its current state will cause the storyboard to start – if the view model’s IsFirstUse value is changed to False, the storyboard will not be started when the application loads.&lt;/p&gt;
&lt;p&gt;This is just one example of how you might use a condition on an action – hopefully you’ll find them useful in many other situations.&lt;/p&gt;</description><pubDate>Sun, 07 Oct 2012 20:23:43 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/conditional-trigger-actions-with-winrttriggers</guid></item><item><title>Triggers in WinRT XAML</title><link>http://www.goatly.net:80/triggers-in-winrt-xaml</link><description>&lt;blockquote&gt;
&lt;p&gt;All the code for WinRTTriggers is available from the &lt;a href="https://winrttriggers.codeplex.com/" target="_blank"&gt;CodePlex project site&lt;/a&gt;, and is available in binary form in a &lt;a href="https://nuget.org/packages/WinRTTriggers" target="_blank"&gt;nuget package&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A few months ago I attended one of Microsoft's "Windows Phone to Windows 8 App" events. The intent was to take &lt;a href="http://www.goatly.net/equazor" target="_blank"&gt;Equazor&lt;/a&gt;and migrate it to a Windows Store application as much as possible over the space of two days.&lt;/p&gt;
&lt;p&gt;On the whole, the event was really useful to just hang out with a bunch of other developers (along with some Microsofties like &lt;a href="http://mtaulty.com/" target="_blank"&gt;Mike Taulty&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/b/thebeebs/" target="_blank"&gt;Martin Beeby&lt;/a&gt;) and I managed to port all the "business logic" of the app pretty successfully - you would expect so given that I had used the MVVM pattern with &lt;a href="http://mvvmlight.codeplex.com/" target="_blank"&gt;MvvmLight&lt;/a&gt;, which is now available for WinRT XAML applications.&lt;/p&gt;
&lt;p&gt;Where I became unstuck, however, was my reliance on Expression Blend's triggers to manipulate the UI in response to the changing view model and handle the player's interactions; as it turns out these are not currently supported by in the WinRT XAML world.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;So what's a was I to do, but write my own implementation?&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Introducing WinRTTriggers&lt;/h2&gt;
&lt;p&gt;The best way to explain the sort of things you can do with WinRTTriggers is to show a quick snippet of XAML from the test app that&amp;rsquo;s available in the solution:&lt;/p&gt;
&lt;pre class="html"&gt;&amp;lt;Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}" 
        DataContext="{StaticResource ViewModel}"&amp;gt;
    &amp;lt;Triggers:Interactions.Triggers&amp;gt;
        &amp;lt;Triggers:PropertyChangedTrigger Binding="{Binding Person.Name}"&amp;gt;
            &amp;lt;Triggers:ControlStoryboardAction Action="Start" 
                Storyboard="{StaticResource FlashNameChanged}" /&amp;gt;
        &amp;lt;/Triggers:PropertyChangedTrigger&amp;gt;
        ...
        &amp;lt;Triggers:PropertySetTrigger Binding="{Binding Person.IsHappy}" 
                RequiredValue="false"&amp;gt;
            &amp;lt;Triggers:GotoStateAction StateName="Sad" /&amp;gt;
        &amp;lt;/Triggers:PropertySetTrigger&amp;gt;
    &amp;lt;/Triggers:Interactions.Triggers&amp;gt;

    &amp;lt;VisualStateManager.VisualStateGroups&amp;gt;
        &amp;lt;VisualStateGroup x:Name="HappySad"&amp;gt;
            &amp;lt;VisualStateGroup.Transitions&amp;gt;&lt;/pre&gt;
&lt;p&gt;There are 2 triggers demonstrated above:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first watches the &lt;strong&gt;Person.Name&lt;/strong&gt; property &amp;ndash; when it is modified, it reacts by starting the &lt;strong&gt;FlashNameChanged&lt;/strong&gt;storyboard.&lt;/li&gt;
&lt;li&gt;The second watches the &lt;strong&gt;Person.IsHappy&lt;/strong&gt; property &amp;ndash; when it gets set to &lt;strong&gt;false&lt;/strong&gt;, it reacts by changing the visual state to &lt;strong&gt;Sad&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From this it should be relatively obvious that there&amp;rsquo;s a very simple trigger/action relationship going on here &amp;ndash; you configure a trigger and specify the action that should happen as a result of it firing.&lt;/p&gt;
&lt;h3&gt;Triggers&lt;/h3&gt;
&lt;p&gt;Currently implemented are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PropertyChangedTrigger - fires when a property changes to any value&lt;/li&gt;
&lt;li&gt;PropertySetTrigger - like PropertyChangedTrigger, except it will only get fire when a property changes to a specified value.&lt;/li&gt;
&lt;li&gt;EventTrigger - fires when an event associated to the control is fired, e.g. the Tapped event on a control.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Actions&lt;/h3&gt;
&lt;p&gt;The current actions are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GotoStateAction - Instructs the VisualStateManager to change to a named state&lt;/li&gt;
&lt;li&gt;InvokeCommandAction - Invokes some ICommand implementation, probably located on your view model.&lt;/li&gt;
&lt;li&gt;ControlStoryboardAction - Starts/Stops/Pauses a storyboard.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Todo&amp;hellip;&lt;/h2&gt;
&lt;p&gt;There are some things that I know are missing, I definitely haven't covered all the triggers and that Expression did - I imagine these will be added over time.&lt;/p&gt;
&lt;p&gt;Another big omission is the inability to apply conditions to triggers, i.e. only fire this trigger is some arbitrary value is true. I may (or may not) tackle these soon, depending on how much I need them!&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;I still haven&amp;rsquo;t got the Equazor port done yet, but I&amp;rsquo;ve had fun getting this framework up and running over some (very) limited free time. I think that even with just these few triggers I think you'll be able to replicate a reasonable amount of the old Blend interaction logic.&lt;/p&gt;
&lt;p&gt;Let me know if you encounter any problems or have any requests.&lt;/p&gt;</description><pubDate>Fri, 28 Sep 2012 16:04:00 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/triggers-in-winrt-xaml</guid></item><item><title>Equazor</title><link>http://www.goatly.net:80/equazor</link><description>&lt;p&gt;&lt;img width="205" height="336" title="equazor_equationcomplete" align="right" style="background-image: none; float: right; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" alt="equazor_equationcomplete" src="http://www.goatly.net/Media/Default/Windows-Live-Writer/Equazor_9555/equazor_equationcomplete_3.png" border="0" /&gt;A couple of months ago I released my first Windows Phone game into the wild. It&amp;rsquo;s a &amp;ldquo;maths-based puzzle game&amp;rdquo; that will challenge, infuriate (hopefully not too much!) and with a bit of practice, genuinely develop your mental arithmetic.&lt;/p&gt;
&lt;p&gt;The premise is simple &amp;ndash; you have to highlight a sequence of tiles forming an equation that results in a target number. It&amp;rsquo;s easy to start with, with just add and subtract and a limited number of tiles to play with, but it soon gets harder when the multiplication is introduced and the playing area and target numbers get larger. Oh, and you&amp;rsquo;re up against the clock, so there is some pressure!&lt;/p&gt;
&lt;p&gt;You can get Equazor from the &lt;a href="http://www.windowsphone.com/en-gb/store/app/equazor/71b3f9b5-16aa-40ea-a2aa-3b7c46f3f538" target="_blank"&gt;Windows Phone Marketplace&lt;/a&gt; or by searching for it on your Windows Phone &amp;ndash; it&amp;rsquo;s free, so what have you got to lose? Let me know what you think!&lt;/p&gt;
&lt;h2&gt;Tech talk&lt;/h2&gt;
&lt;p&gt;Just in case you&amp;rsquo;re interested, I developed it in Silverlight with all the logic being held together with &lt;a href="http://mvvmlight.codeplex.com/" target="_blank"&gt;MvvmLight&lt;/a&gt;. The main chunk of development took place over three days, with a following day or two needed to polish and test it.&lt;/p&gt;</description><pubDate>Thu, 20 Sep 2012 21:08:00 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/equazor</guid></item><item><title>New host, new look</title><link>http://www.goatly.net:80/new-host-new-look</link><description>&lt;p&gt;There hasn&amp;rsquo;t been much activity here for a while for several reasons, including a new job and the small matter of a total server failure for a few months&amp;hellip;&lt;/p&gt;
&lt;p&gt;&amp;hellip;but now I&amp;rsquo;m back. I&amp;rsquo;m on a new host, a new platform (&lt;a href="http://orchardproject.net/" target="_blank"&gt;Orchard&lt;/a&gt;) and have a new look that I threw together &amp;ndash; ok, I&amp;rsquo;m no professional graphic designer, but hey, it adapts to small screens nicer than the last one did!&lt;/p&gt;
&lt;p&gt;Please bear with me as I work out&amp;nbsp;any kinks in the new site, and stay tuned - I&amp;rsquo;ve got a few plans for this blog.&lt;/p&gt;</description><pubDate>Wed, 19 Sep 2012 19:09:00 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/new-host-new-look</guid></item><item><title>Export all tables in an Access database to CSV</title><link>http://www.goatly.net:80/2012/5/29/Export-all-tables-in-an-Access-database-to-CSV.aspx</link><description>&lt;p&gt;I don't usually mess around with Access much, but when I do it's usually to have it act as an intermediary data source while I'm getting data from one format to another.&lt;/p&gt;
&lt;p&gt;I had just such a problem to solve today, and the usually excellent out-of-the-box import/export processes let me down a little. Essentially I needed to get the data from each of the tables into separate CSV files - unfortunately I had quite a few tables to do and the UI only allows you to do one at a time.&lt;/p&gt;
&lt;p&gt;Here's the little VBA routine I put together to solve the problem:&lt;/p&gt;
&lt;pre&gt;Public Sub ExportAllTablesToCSV()

    Dim i As Integer
    Dim name As String
    
    For i = 0 To CurrentDb.TableDefs.Count
        name = CurrentDb.TableDefs(i).name
        
        If Not Left(name, 4) = "msys" And Not Left(name, 1) = "~" Then
            DoCmd.TransferText acExportDelim, , name, _
                "c:\exports\" &amp;amp; name &amp;amp; ".csv", _
                True
        End If
    
    Next i

End Sub
&lt;/pre&gt;</description><pubDate>Tue, 29 May 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/2012/5/29/Export-all-tables-in-an-Access-database-to-CSV.aspx</guid></item><item><title>Why have my visual state changes stopped working?</title><link>http://www.goatly.net:80/2012/5/22/Why-have-my-visual-state-changes-stopped-working.aspx</link><description>&lt;p&gt;This took me a little while to work out, and searching for an answer didn't help me out, so I thought it might be helpful to post this as a pointer to anyone else who encounters the same problem.&lt;/p&gt;
&lt;p&gt;My scenario:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A Silverlight Windows Phone 7.1 App&lt;/li&gt;
&lt;li&gt;a control with a number of visual states applied to it&lt;/li&gt;
&lt;li&gt;Interaction triggers that switch between the various states&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Everything was working fine until I wrapped the root element of my control in another container element - all of a sudden the visual states stopped working &lt;em&gt;at runtime&lt;/em&gt;. As far as the designer was concerned, everything was fine though.&lt;/p&gt;
&lt;p&gt;After a bit of digging around I found that the VisualStateManager.VisualStateGroups element had been moved to the new parent element, but the VisualStateManager.CustomVisualStateManager element that Expression Blend had added in to provide smooth animation and layout had not. Moving the CustomVisualStateManager element to be contained in the root element fixed the problem.&lt;/p&gt;
&lt;p&gt;Hope that helps someone.&lt;/p&gt;</description><pubDate>Tue, 22 May 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/2012/5/22/Why-have-my-visual-state-changes-stopped-working.aspx</guid></item><item><title>Hooking into session start events in an HTTP module</title><link>http://www.goatly.net:80/2012/1/25/Hooking-into-session-start-events-in-an-HTTP-module.aspx</link><description>&lt;p&gt;According to the MSDN documentation you can't handle Session Start events in an HTTP module. The reason for this is because when you are initialising an HTTP module you hook into events associated to the HttpApplication class, and HttpApplication doesn't expose any events relating to the starting of sessions.&lt;/p&gt;
&lt;p&gt;As a refresher, the Init method will typically look like something like this:&lt;/p&gt;
&lt;pre class="code"&gt;public void Init(HttpApplication context)
{
    // Hook into the HttpApplication events you want to respond to
    context.BeginRequest += this.BeginRequest;
}
&lt;/pre&gt;
&lt;p&gt;So it's not possible&amp;hellip; right? Wrong, but only if you don't mind a slightly dirty hack.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;I should probably make the standard disclaimer for this sort of thing - it works on my machine! -&amp;nbsp; There are no guarantees if it will work in your environment, and would strongly recommend testing it fully!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The trick is getting access to the &lt;em&gt;SessionStateModule&lt;/em&gt; in the Init method, and hooking into the Start event from there, like this:&lt;/p&gt;
&lt;pre class="code"&gt;public void Init(HttpApplication context)
{
    var module = context.Modules["Session"] as SessionStateModule;
    if (module != null)
    {
        module.Start += this.Session_Start;
    }
}

private void Session_Start(object sender, EventArgs e)
{
    // Respond to the session start event however you need
}
&lt;/pre&gt;
&lt;p&gt;This works by relying on the fact that there's a module in the application's HttpModuleCollection called &lt;em&gt;Session -&lt;/em&gt; a fairly safe bet unless you're really messing with the httpModules definition in the .NET Framework's web.config file. Note, however, it could break if a new version of the framework comes along and names the module differently, but it hasn't changed in any of the framework versions that have been released to date.&lt;/p&gt;</description><pubDate>Wed, 25 Jan 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/2012/1/25/Hooking-into-session-start-events-in-an-HTTP-module.aspx</guid></item><item><title>Article on using SqlBulkCopy with POCOs</title><link>http://www.goatly.net:80/2012/1/20/Article-on-using-SqlBulkCopy-with-POCOs.aspx</link><description>
&lt;p&gt;I realised that I never pushed this on my blog at all, so
belatedly I will.&lt;/p&gt;

&lt;p&gt;Last year I wrote an article for Developer Fusion that discussed
how you could make use of SqlBulkCopy to do high performance
inserts when you were working with POCOs, rather than inserting
them entity by entity using an ORM.&lt;/p&gt;

&lt;p&gt;The bottom line was that inserting 10,000 records took only 57ms
using the generic SqlBulkCopy approach I describe, rather than
2159ms to insert them on a record-by-record basis.&lt;/p&gt;

&lt;p&gt;You can check the article out here: &lt;a href="http://www.developerfusion.com/article/122498/using-sqlbulkcopy-for-high-performance-inserts/" target="_blank"&gt;Using SqlBulkCopy for high performance
inserts&lt;/a&gt;&lt;/p&gt;
</description><pubDate>Fri, 20 Jan 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/2012/1/20/Article-on-using-SqlBulkCopy-with-POCOs.aspx</guid></item><item><title>DynaCache- just like page output caching, but for classes</title><link>http://www.goatly.net:80/2012/1/15/DynaCache-just-like-page-output-caching,-but-for-classes.aspx</link><description>
&lt;p&gt;Anyone who has done any serious work with any ASP.NET based
framework will know that page output caching is a great feature.
For those not familiar with it, the basic premise is that it makes
sure that the generation of content is done only once for a set of
parameters, and that all subsequent requests with the same
parameters are served up from the cache for a specified period of
time.&lt;/p&gt;

&lt;p&gt;Wouldn't it be nice if you could do a similar thing for methods
on classes, just by applying an attribute like this?&lt;/p&gt;

&lt;pre class="code"&gt;
[CacheableMethod(30)]
public virtual string GetData(int id)
&lt;/pre&gt;

&lt;p&gt;Thanks to a little library called &lt;a href="http://dynacache.codeplex.com/" target="_blank"&gt;DynaCache&lt;/a&gt;, you can!&lt;/p&gt;

&lt;h2&gt;How does it work?&lt;/h2&gt;

&lt;p&gt;Say you have a class called TestClass:&lt;/p&gt;

&lt;p&gt;&lt;img src="/Media/Default/media/1564/initialhierarchy.png" width="355" height="198" alt="image" border="0" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px; border: 0;"&gt;&lt;/p&gt;

&lt;p&gt;The LoadData method is marked as virtual, and has an attribute
called CacheableMethod applied to it, indicating the number of
seconds the results should be cached for.&lt;/p&gt;

&lt;p&gt;The CachableMethod attribute is the first interaction with the
DynaCache framework - the second is with a class called
Cacheable:&lt;/p&gt;

&lt;p&gt;&lt;img src="/Media/Default/media/1569/Windows-Live-Writer_80eb766f89d3_AD04_image_0f38d0f3-6b54-41f4-9aea-7d2d2bddbac3.png" width="232" height="119" alt="image" border="0" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;"&gt;&lt;/p&gt;

&lt;p&gt;Calling &lt;em&gt;Cacheable.CreateType&amp;lt;TestClass&amp;gt;()&lt;/em&gt; at
runtime creates a new class called &lt;em&gt;CacheableTestClass&lt;/em&gt;,
deriving from TestClass and overriding any methods with the
CachableMethod attribute, resulting in a class hierarchy like
this:&lt;/p&gt;

&lt;p&gt;&lt;img src="/Media/Default/media/1574/fullhierarchy.png" width="356" height="322" alt="image" border="0" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px; border: 0; margin: 0px;"&gt;&lt;/p&gt;

&lt;p&gt;This new class is created using Reflection.Emit and only exists
in memory, so you can't use a reflector-like program to see what's
generated, but if you could it would look something like this:&lt;/p&gt;

&lt;pre class="code"&gt;
public class CacheableTestClass : TestClass
{
    private IDynaCacheService cacheService;
    
    public TestClass(IDynaCacheService cacheService)
    {
        this.cacheService = cacheService;
    }

    public override string LoadData(int id)
    {
        string cacheKey = String.Format(CultureInfo.InvariantCulture, "TestClass_LoadData(Int32).{0}", id);
        object result;
        if (!this.cacheService.TryGetCachedObject(cacheKey, out result))
        {
            result = base.LoadData(id);
            this.cacheService.SetCachedObject(cacheKey, result, 200);
        }
        
        return (string)result;
    }
}
&lt;/pre&gt;

&lt;p&gt;Notice the IDynaCacheService parameter in the constructor?
That's the third piece of the DynaCache framework - an instance of
a class capable of interacting with whatever backing cache is being
used. Out of the box DynaCache includes a concrete implementation
of this called MemoryCacheService - it's just a wrapper around a
.NET 4 MemoryCache instance. There's no reason why you shouldn't
create your own though, e.g. for the ASP.NET or Windows Azure
cache.&lt;/p&gt;

&lt;h2&gt;Making it simple with dependency injection&lt;/h2&gt;

&lt;p&gt;What this all means is that at runtime you need to be using
CacheableTestClass rather than TestClass, otherwise all the
generated caching code will never be used. Although it's possible
to construct and use these types yourself, the simplest and best
way to do that is to use a dependency injection framework, such as
Ninject, StructureMap, etc.&lt;/p&gt;

&lt;p&gt;For the sake of illustration, I'm going to use Ninject. The
original configuration would have simply mapped ITestClass to
TestClass, like this:&lt;/p&gt;

&lt;pre class="code"&gt;
kernel.Bind&amp;lt;ITestClass&amp;gt;().To&amp;lt;TestClass&amp;gt;();
&lt;/pre&gt;

&lt;p&gt;Using DynaCache is only marginally more complicated, you just
configure your kernel like this:&lt;/p&gt;

&lt;pre class="code"&gt;
kernel.Bind&amp;lt;IDynaCacheService&amp;gt;().To&amp;lt;MemoryCacheService&amp;gt;();
kernel.Bind&amp;lt;ITestClass&amp;gt;().To(Cacheable.CreateType&amp;lt;TestClass&amp;gt;());
&lt;/pre&gt;

&lt;p&gt;The first line configures the cache service to pass to instances
of CacheableTestClass&lt;em&gt;,&lt;/em&gt; whilst the second binds ITestClass
to the cacheable version of TestClass.&lt;/p&gt;

&lt;p&gt;That's all there is to it! Now every time an instance of
ITestClass is required, Ninject will construct and return an
instance of CacheableTestClass - the rest of your code that
consumes ITestClass will automatically make use of the dynamically
constructed caching code.&lt;/p&gt;

&lt;h2&gt;Where to get DynaCache&lt;/h2&gt;

&lt;p&gt;You can get it from the &lt;a href="http://dynacache.codeplex.com/" target="_blank"&gt;CodePlex project site&lt;/a&gt;, or you can install it
into your project using the Nuget command:&lt;/p&gt;

&lt;pre&gt;
Install-Package DynaCache
&lt;/pre&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;Hopefully all the detail hasn't put you off - this whole article
essentially boils down to just these three steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make the methods overridable and apply the CacheableMethod
attribute to them.&lt;/li&gt;

&lt;li&gt;Configure your DI framework to return an instance of
IDynaCacheService, either MemoryCacheService or one you have
implemented yourself.&lt;/li&gt;

&lt;li&gt;Configure your DI framework to return the result of
&lt;em&gt;Cacheable.CreateType&lt;/em&gt; for your type.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'd be really interested in feedback for DynaCache - let me know
your thoughts in comments below, or on the project discussion
board.&lt;/p&gt;
</description><pubDate>Sun, 15 Jan 2012 00:00:00 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/2012/1/15/DynaCache-just-like-page-output-caching,-but-for-classes.aspx</guid></item><item><title>Tutorial: Using LIFTI in an MVC 3 web application</title><link>http://www.goatly.net:80/2011/7/1/Tutorial-Using-LIFTI-in-an-MVC-3-web-application.aspx</link><description>
&lt;p&gt;&lt;em&gt;Updated 25/02/2012 - it was highlighted that some of the
seach phrases used towards the end of this article were not
returning the expected results - that was down to me making
assumptions about which words would be stemmed - these examples
have been updated.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This tutorial will take you through an end-to-end implementation
of a simple web site to manage a list of employees. LIFTI will be
used to perform full text searching of plain text information
associated to the employees.&lt;/p&gt;

&lt;p&gt;Whilst the site will be built upon MVC 3, Entity Framework Code
First and Ninject, the use of these technologies is largely
arbitrary - you should be able to switch them out for any other
appropriate frameworks.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Important: This tutorial relies on you having &lt;a href="http://nuget.org/" target="_blank"&gt;nuget&lt;/a&gt; installed -
trust me, it makes the process of setting up your project
dependencies &lt;em&gt;so&lt;/em&gt; much easier.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;Getting started&lt;/h2&gt;

&lt;p&gt;To get started, create a new empty MVC 3 application so you have
a basic structure for the web application to be built from.&lt;/p&gt;

&lt;p&gt;&lt;a href="/media/1482/Windows-Live-Writer_Using-LIFTI-in-an-MVC-3-web-application_9CFE_image_4.png"&gt;
&lt;img src="/Media/Default/media/1487/Windows-Live-Writer_Using-LIFTI-in-an-MVC-3-web-application_9CFE_image_thumb_1.png" width="497" height="315" alt="image" border="0" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="/media/1492/Windows-Live-Writer_Using-LIFTI-in-an-MVC-3-web-application_9CFE_image_6.png"&gt;
&lt;img src="/Media/Default/media/1497/Windows-Live-Writer_Using-LIFTI-in-an-MVC-3-web-application_9CFE_image_thumb_2.png" width="360" height="324" alt="image" border="0" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now use &lt;a href="http://nuget.org/" target="_blank"&gt;nuget&lt;/a&gt; to
add LIFTI - open the &lt;strong&gt;Package Manager Console&lt;/strong&gt;
(View/Other Windows/Package Manager Console) and type:&lt;/p&gt;

&lt;pre&gt;
Install-Package LIFTI
&lt;/pre&gt;

&lt;p&gt;The LIFTI assembly will be downloaded and added as a reference
to your project.&lt;/p&gt;

&lt;p&gt;Install the EntityFramework.SqlServerCompact and Ninject.MVC3
packages using the package manager:&lt;/p&gt;

&lt;pre&gt;
Install-Package EntityFramework.SqlServerCompact
Install-Package Ninject.MVC3
&lt;/pre&gt;

&lt;p&gt;Adding these packages will automatically pull through all these
packages (some of them are the dependencies of the two you
added):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EntityFramework&lt;/li&gt;

&lt;li&gt;WebActivator&lt;/li&gt;

&lt;li&gt;SqlServerCompact&lt;/li&gt;

&lt;li&gt;EntityFramework.SqlServerCompact&lt;/li&gt;

&lt;li&gt;Ninject&lt;/li&gt;

&lt;li&gt;Ninject.MVC3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both Ninject.MVC3 and EntityFramework.SqlServerCompact packages
add code files into a folder called App_Start. The SqlServerCompact
class configures the default connection factory for the entity
framework library to use the SQL Server Compact connection factory;
the NinjectMVC3 class allows you to configure your dependency
injection - you'll come onto that later.&lt;/p&gt;

&lt;h2&gt;Create a model and data context&lt;/h2&gt;

&lt;p&gt;Add Employee.cs to the Models folder of the project
containing:&lt;/p&gt;

&lt;pre class="code"&gt;
public class Employee
{
    [Key]
    public int EmployeeId { get; set; }

    [StringLength(100), Required]
    public string Name { get; set; }

    [Required]
    public DateTime DateOfEmployment { get; set; }

    public string Notes { get; set; } 
}
&lt;/pre&gt;

&lt;p&gt;Add EmployeeDataContext.cs to the Models folder:&lt;/p&gt;

&lt;pre class="code"&gt;
public class EmployeeDataContext : DbContext
{
    public DbSet&amp;lt;Employee&amp;gt; Employees
    {
        get;
        set;
    }
}
&lt;/pre&gt;

&lt;h2&gt;Scaffold out the site&lt;/h2&gt;

&lt;p&gt;Make sure that you have built the project and right-click on the
Controllers folder, selecting &lt;strong&gt;Add Controller…&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name the controller EmployeesController&lt;/li&gt;

&lt;li&gt;Make sure the template "Controller with read/write actions and
views…" is selected&lt;/li&gt;

&lt;li&gt;Select Employee as the model&lt;/li&gt;

&lt;li&gt;Select EmployeeDataContext as the data context&lt;/li&gt;

&lt;li&gt;Press Add&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The scaffolded actions and views will be created for you (very
handy in tutorials like this!).&lt;/p&gt;

&lt;p&gt;Before you run the project, &lt;a href="/2011/6/27/entity-framework-code-first-the-path-is-not-valid-check-the-directory-for-the-database.aspx" target="_blank"&gt;make sure you have added the App_Data ASP.NET
folder&lt;/a&gt; to the project by right clicking on the project and
selecting Add &amp;gt; Add ASP.NET Folder &amp;gt; App_Data.&lt;/p&gt;

&lt;p&gt;At this point you should be able to run the project to make sure
that everything you've done so far is correct. You should be able
to fire up the project and navigate to
&lt;em&gt;http://localhost:xxxx/Employees&lt;/em&gt; where xxxx is the port
number for your project:&lt;/p&gt;

&lt;p&gt;&lt;a href="/media/1502/Windows-Live-Writer_Using-LIFTI-in-an-MVC-3-web-application_9CFE_image_10.png"&gt;
&lt;img src="/Media/Default/media/1507/Windows-Live-Writer_Using-LIFTI-in-an-MVC-3-web-application_9CFE_image_thumb_4.png" width="531" height="219" alt="image" border="0" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok, so it doesn't look very sexy, but it's a website with a SQL
Server Compact database sitting behind it, all up and running in
just a few steps.&lt;/p&gt;

&lt;h2&gt;Introducing LIFTI&lt;/h2&gt;

&lt;p&gt;The full text index that you will be using is an updatable full
text index that will contain the IDs of employees indexed against
the text in their notes. More specifically, this will be an
instance of PersistedFullTextIndex&amp;lt;int&amp;gt; - this type of index
is backed by a file store, which means that if the web application
is stopped and started, the index will not lose all its data and
will be able to pick up where it left off. Significantly this means
that you will be able to keep the index and database in sync,
assuming that whenever the database is updated you also update the
index.&lt;/p&gt;

&lt;p&gt;Under most circumstances there should only ever be one instance
of your index in memory. This means that all of your code, whatever
thread it is on, should interact with the same index (don't worry,
LIFTI's implementation of the full text index is thread safe.). You
could implement this is any number of ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using the singleton pattern&lt;/li&gt;

&lt;li&gt;Storing the index in a static variable somewhere that can be
access by the depending code&lt;/li&gt;

&lt;li&gt;Storing the index in Application state&lt;/li&gt;

&lt;li&gt;Using dependency injection to provide one common index to any
depending code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Like all good developers these days, I'm sure you'll want to
take the dependency injection route! The first step to this is to
add your index into the dependency injection framework.&lt;/p&gt;

&lt;p&gt;Open App_Start\NinjectMVC3.cs and change the RegisterServices
method so it looks like this:&lt;/p&gt;

&lt;pre class="code"&gt;
private static void RegisterServices(IKernel kernel)
{
    string filePath = Path.Combine(
        (string)AppDomain.CurrentDomain.GetData("DataDirectory"), 
        "Index.dat");

    kernel.Bind&amp;lt;IUpdatableFullTextIndex&amp;lt;int&amp;gt;&amp;gt;()
        .To&amp;lt;PersistedFullTextIndex&amp;lt;int&amp;gt;&amp;gt;()
        .InSingletonScope()
        .WithConstructorArgument("backingFilePath", filePath)
        .OnActivation((IUpdatableFullTextIndex&amp;lt;int&amp;gt; i) =&amp;gt;
        {
            i.WordSplitter = new StemmingWordSplitter();
            i.QueryParser = new LiftiQueryParser();
        });
}
&lt;/pre&gt;

&lt;p&gt;The &lt;strong&gt;filePath&lt;/strong&gt; variable is configured so that the
index data file (index.dat) will be stored in the App_Data folder
for the application. (that's where "DataDirectory" points by
default in a web application.)&lt;/p&gt;

&lt;p&gt;Then the Ninject kernel is instructed that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whenever an instance of IUpdatableFullTextIndex&amp;lt;int&amp;gt; is
requested (&lt;strong&gt;Bind&lt;/strong&gt;)&lt;/li&gt;

&lt;li&gt;Map it to an instance of PersistedFullTextIndex&amp;lt;int&amp;gt;
(&lt;strong&gt;To&lt;/strong&gt;)&lt;/li&gt;

&lt;li&gt;And re-use it globally, i.e. only ever create one instance
(&lt;strong&gt;InSingletonScope&lt;/strong&gt;)&lt;/li&gt;

&lt;li&gt;When it is constructed, pass the path to the index data to the
"backingFilePath" parameter
(&lt;strong&gt;WithConstructorArgument&lt;/strong&gt;)&lt;/li&gt;

&lt;li&gt;And finally, when it is activated, set the WordSplitter and
QueryParser properties to instances of &lt;a href="http://lifti.codeplex.com/wikipage?title=Word%20splitters&amp;amp;referringTitle=Documentation" target="_blank"&gt;StemmingWordSplitter&lt;/a&gt; and &lt;a href="http://lifti.codeplex.com/wikipage?title=Searching%20the%20full%20text%20index&amp;amp;referringTitle=Documentation" target="_blank"&gt;LiftiQueryParser&lt;/a&gt;, respectively.
(&lt;strong&gt;OnActivation&lt;/strong&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you just have to consume the index and use it in the
controller.&lt;/p&gt;

&lt;h2&gt;Updating the index&lt;/h2&gt;

&lt;p&gt;Open the EmployeesController class and add a constructor:&lt;/p&gt;

&lt;pre class="code"&gt;
private IUpdatableFullTextIndex&amp;lt;int&amp;gt; index;
public EmployeesController(IUpdatableFullTextIndex&amp;lt;int&amp;gt; index)
{
    this.index = index;
}
&lt;/pre&gt;

&lt;p&gt;Ninject (in conjunction with the nice dependency resolution in
MVC 3) will take care of providing your controller with the
relevant instance of the index whenever it is constructed.&lt;/p&gt;

&lt;p&gt;There are 3 places in the controller that you need to interact
with the index to keep it in sync with the database:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating an employee - the index should be updated if notes are
provided for the employee&lt;/li&gt;

&lt;li&gt;Updating an employee - the index should be updated if the
employee has notes, or have any indexed text removed if the
employee no longer has any notes&lt;/li&gt;

&lt;li&gt;Deleting an employee - any previously indexed notes for the
employee should be removed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Update the HttpPost Create method so it looks like this:&lt;/p&gt;

&lt;pre class="code"&gt;
[HttpPost]
public ActionResult Create(Employee employee)
{
    if (ModelState.IsValid)
    {
        db.Employees.Add(employee);
        db.SaveChanges();

 &lt;strong&gt;    if (!String.IsNullOrEmpty(employee.Notes))
        {
            this.index.Index(employee.EmployeeId, employee.Notes);
        }&lt;/strong&gt;

        return RedirectToAction("Index");  
    }

    return View(employee);
}
&lt;/pre&gt;

&lt;p&gt;Then the HttpPost Edit method:&lt;/p&gt;

&lt;pre class="code"&gt;
[HttpPost]
public ActionResult Edit(Employee employee)
{
    if (ModelState.IsValid)
    {
        db.Entry(employee).State = EntityState.Modified;
        db.SaveChanges();

 &lt;strong&gt;    if (String.IsNullOrEmpty(employee.Notes))
        {
            this.index.Remove(employee.EmployeeId);
        }
        else
        {
            this.index.Index(employee.EmployeeId, employee.Notes);
        }&lt;/strong&gt;

        return RedirectToAction("Index");
    }
    return View(employee);
}
&lt;/pre&gt;

&lt;p&gt;And finally, the HttpPost Delete method:&lt;/p&gt;

&lt;pre class="code"&gt;
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{            
    Employee employee = db.Employees.Find(id);
    db.Employees.Remove(employee);
    db.SaveChanges();

 &lt;strong&gt;this.index.Remove(employee.EmployeeId);&lt;/strong&gt;

    return RedirectToAction("Index");
}
&lt;/pre&gt;

&lt;p&gt;Try the application out again, you should be able to create,
update and delete employees without any problems - the full text
index will be built up in the background.&lt;/p&gt;

&lt;h2&gt;Searching for employees&lt;/h2&gt;

&lt;p&gt;The last step is to allow users of your site to search for
interesting text within the employee notes.&lt;/p&gt;

&lt;p&gt;Update the Views\Employees\index.cshtml file with a search
textbox just after the &amp;lt;h2&amp;gt; tag:&lt;/p&gt;

&lt;pre class="html"&gt;
&amp;lt;h2&amp;gt;Index&amp;lt;/h2&amp;gt;

@using (Html.BeginForm()) {
&amp;lt;p&amp;gt;
    @Html.Label("searchCriteria", "Search employee notes:")
    @Html.TextBox("searchCriteria") 
    &amp;lt;input type="submit" value="Search" /&amp;gt;
&amp;lt;/p&amp;gt;
}
&lt;/pre&gt;

&lt;p&gt;Now add a new method to the EmployeesController to handle the
posting of the search text:&lt;/p&gt;

&lt;pre class="code"&gt;
[HttpPost]
public ViewResult Index(string searchCriteria)
{
    if (String.IsNullOrEmpty(searchCriteria))
    {
        return Index();
    }

    var matchingIds = this.index.Search(searchCriteria).ToArray();
    var employees = this.db.Employees
        .Where(e =&amp;gt; matchingIds.Contains(e.EmployeeId))
        .ToList();

    return View(employees);
}
&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;The astute amongst you will notice that the data context
isn't injected in the same way that the index is - good spot. This
tutorial is long enough, so I'll leave that as an exercise for you
to fix up if it's bugging you that much!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;Testing the application&lt;/h2&gt;

&lt;p&gt;Build and run the project create these employees:&lt;/p&gt;

&lt;table border="0" width="648" cellspacing="0" cellpadding="2"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="133" valign="top"&gt;Name&lt;/td&gt;
&lt;td width="133" valign="top"&gt;Date of employment&lt;/td&gt;
&lt;td width="380" valign="top"&gt;Notes&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td width="133" valign="top"&gt;Ralph&lt;/td&gt;
&lt;td width="133" valign="top"&gt;12/08/2008&lt;/td&gt;
&lt;td width="380" valign="top"&gt;Often arriving late to work and
frequently takes long lunch breaks&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td width="133" valign="top"&gt;Tracy&lt;/td&gt;
&lt;td width="133" valign="top"&gt;02/02/2010&lt;/td&gt;
&lt;td width="380" valign="top"&gt;New employee, very diligent worker,
and no-one is doubting their commitment, but sometimes acts
suspicious when asked about the amount of sick leave taken&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td width="133" valign="top"&gt;Bob&lt;/td&gt;
&lt;td width="133" valign="top"&gt;23/11/2003&lt;/td&gt;
&lt;td width="380" valign="top"&gt;Works long hours. Arrives early to
work and generally stays later than others and works through lunch.
Has a tendency to break the build with a high frequency
though.&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td width="133" valign="top"&gt;Andy&lt;/td&gt;
&lt;td width="133" valign="top"&gt;10/08/2007&lt;/td&gt;
&lt;td width="380" valign="top"&gt;Very clean desk - there are doubts
that he doesn't actually do anything at work&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;
 Try some of these search criteria on the index page:&lt;/p&gt;

&lt;h3&gt;doubts&lt;/h3&gt;

&lt;p&gt;Andy is obviously matched - in his notes he has "doubts"
specified exactly. However there's more going on here because Tracy
is also matched. This is because you're using the stemming word
splitter process words in the index, and that automatically removes
some word suffixes, such as the "s" from "doubts" and "ing" in
Tracy's "doubting" - this means that when you searched for "doubts"
you were actually searching for anything that stemmed to
"doubt".&lt;/p&gt;

&lt;h3&gt;emp&lt;/h3&gt;

&lt;p&gt;Nothing will come back - not even Tracy. This is because the
default behaviour for the LIFTI query parser is to match words
exactly.&lt;/p&gt;

&lt;h3&gt;emp*&lt;/h3&gt;

&lt;p&gt;Tracy will be returned - she is the only employee with notes
containing a word that starts with "emp".&lt;/p&gt;

&lt;h3&gt;lunch &amp;amp; break (or lunch break)&lt;/h3&gt;

&lt;p&gt;Both Ralph and Bob will be returned - both of these contain
derivatives of "lunch" and "break" in their notes.&lt;/p&gt;

&lt;h3&gt;"lunch break"&lt;/h3&gt;

&lt;p&gt;Only Ralph contains a phrase that contains "lunch" followed
immediately by a derivative of "break".&lt;/p&gt;

&lt;h3&gt;… your search criteria here&lt;/h3&gt;

&lt;p&gt;The LIFTI search engine is quite powerful and there are &lt;a href="http://lifti.codeplex.com/wikipage?title=Searching%20the%20full%20text%20index&amp;amp;referringTitle=Documentation" target="_blank"&gt;loads of different search permutations&lt;/a&gt; you
could try out, so try creating a few more employees and searching
using some of the other operators, such as or (|) or near (~).&lt;/p&gt;
</description><pubDate>Fri, 01 Jul 2011 00:00:00 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/2011/7/1/Tutorial-Using-LIFTI-in-an-MVC-3-web-application.aspx</guid></item><item><title>Entity Framework Code First: "The path is not valid. Check the directory for the database"</title><link>http://www.goatly.net:80/2011/6/27/Entity-Framework-Code-First-The-path-is-not-valid-Check-the-directory-for-the-database.aspx</link><description>
&lt;p&gt;If you create a new MVC application and try to go down the Code
First with SQL Server Compact route, you might encounter this error
when you first start the application:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The path is not valid. Check the directory for the
database.&lt;/em&gt; &lt;em&gt;[ Path = …\WebSample\App_Data\YourDatabase.sdf
]&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This error might be a surprise because by default the code first
approach should create the database for you if it doesn't already
exist.&lt;/p&gt;

&lt;p&gt;Whilst this is true, what it apparently &lt;em&gt;won't&lt;/em&gt; do is
create any parent folders that the database will be stored under -
in this case the &lt;strong&gt;App_Data&lt;/strong&gt; folder. Adding this
folder is easily accomplished by right-clicking on your project and
selecting &lt;em&gt;Add/ASP.NET Folder/App_Data&lt;/em&gt;. Once you've done
this, everything should work as expected.&lt;/p&gt;

&lt;p&gt;As an aside, the reason it's getting created in the App_Data
folder is because that's the default location for "DataDirectory"
in a web application. You might have seen this mentioned in sample
connection strings like this:&lt;/p&gt;

&lt;pre class="code"&gt;
&amp;lt;connectionStrings&amp;gt;
    &amp;lt;add name="MyDataContext" 
        providerName="System.Data.SqlServerCe.4.0" 
        connectionString="Data Source=&lt;strong&gt;|DataDirectory|&lt;/strong&gt;MyDatabase.sdf" /&amp;gt;
&amp;lt;/connectionStrings&amp;gt;
&lt;/pre&gt;

&lt;p&gt;You might get this error even if you're not explicitly
specifying the connection string, as a very similar connection
string will be used by convention if you don't provide one.&lt;/p&gt;
</description><pubDate>Mon, 27 Jun 2011 00:00:00 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/2011/6/27/Entity-Framework-Code-First-The-path-is-not-valid-Check-the-directory-for-the-database.aspx</guid></item><item><title>LIFTI XmlWordSplitter</title><link>http://www.goatly.net:80/2011/6/10/LIFTI-XmlWordSplitter.aspx</link><description>
&lt;p&gt;The XmlWordSplitter is a new word splitter class in the latest
release of LIFTI. I created it mainly because it was required for
the persisted index sample, but it seemed too useful to keep out of
the core framework.&lt;/p&gt;

&lt;p&gt;At a very high level the XmlWordSplitter just enumerates words
contained within elements in a piece of XML text. This means that
element names, attributes and their associated values will not be
indexed. For example, consider the following XML:&lt;/p&gt;

&lt;p&gt;&lt;a href="/media/1366/Windows-Live-Writer_LIFTI-XmlWordSplitter_CEA3_image_2.png"&gt;
&lt;img src="/Media/Default/media/1371/Windows-Live-Writer_LIFTI-XmlWordSplitter_CEA3_image_thumb.png" width="421" height="86" alt="image" border="0" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The xml splitter will return the following words:&lt;/p&gt;

&lt;table border="1" width="400" cellspacing="0" cellpadding="2"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="200" valign="top"&gt;&lt;strong&gt;Word&lt;/strong&gt;&lt;/td&gt;
&lt;td width="200" valign="top"&gt;&lt;strong&gt;Word index&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td width="200" valign="top"&gt;THE&lt;/td&gt;
&lt;td width="200" valign="top"&gt;0, 6&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td width="200" valign="top"&gt;QUICK&lt;/td&gt;
&lt;td width="200" valign="top"&gt;1&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td width="200" valign="top"&gt;BROWN&lt;/td&gt;
&lt;td width="200" valign="top"&gt;2&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td width="200" valign="top"&gt;FOX&lt;/td&gt;
&lt;td width="200" valign="top"&gt;3&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td width="200" valign="top"&gt;JUMPED&lt;/td&gt;
&lt;td width="200" valign="top"&gt;4&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td width="200" valign="top"&gt;OVER&lt;/td&gt;
&lt;td width="200" valign="top"&gt;5&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td width="200" valign="top"&gt;LAZY&lt;/td&gt;
&lt;td width="200" valign="top"&gt;7&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td width="200" valign="top"&gt;DOG&lt;/td&gt;
&lt;td width="200" valign="top"&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Importantly, notice that the word "the" is reported at positions
0 and 6 - the word index is relative to first word in the document,
regardless of whether there are XML elements that interrupt the
flow of the text.&lt;/p&gt;

&lt;h2&gt;To stem or not to stem?&lt;/h2&gt;

&lt;p&gt;One question that sprung to mind when developing this was
whether the splitter should stem the words it returned, like the &lt;a href="/2010/12/7/lifti-and-porter-stemming.aspx" target="_blank"&gt;StemmingWordSplitter&lt;/a&gt;, or just return them
verbatim, like the basic WordSplitter does? (The above example
would be representative of the latter; a stemming word splitter
would have returned words like "jump" instead of "jumped".)&lt;/p&gt;

&lt;p&gt;Taking this question a step further, what if someone has put
together their own custom word splitter and they want the xml
splitter to behave like that?&lt;/p&gt;

&lt;p&gt;To cater for this I decided to defer the splitting of text
contained within XML nodes to a child IWordSplitter implementation.
So when you construct an XmlWordSplitter, you do so like this:&lt;/p&gt;

&lt;pre class="code"&gt;
var wordSplitter = new StemmingWordSplitter();
var xmlSplitter = new XmlWordSplitter(wordSplitter);
&lt;/pre&gt;

&lt;p&gt;So if you don't want the stemming word splitter behaviour for
returned words, you just need to swap it out for a different
implementation. Neat.&lt;/p&gt;

&lt;h2&gt;Splitting search words&lt;/h2&gt;

&lt;p&gt;Previously LIFTI would always use the same word splitter
implementation when splitting words that were being indexed and
words that were being searched upon. Introducing the
XmlWordSplitter had an interesting side-effect - although you were
wanting to index text contained in XML, you probably didn't want to
search for words contained in an XML format.&lt;/p&gt;

&lt;p&gt;To handle this I added the SearchWordSplitter property to the
IFullTextIndex interface - this allows you to specify a different
word splitting implementation that should be used when splitting
words in a search string. As a small token of my &lt;a href="/2011/6/8/changes-to-the-lifti-api.aspx" target="_blank"&gt;respect to backwards compatibility&lt;/a&gt;, if this
property isn't specified or is set to null, then the splitter
specified in the WordSplitter property is used, meaning that
behaviour is unaffected for existing code.&lt;/p&gt;
</description><pubDate>Fri, 10 Jun 2011 00:00:00 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/2011/6/10/LIFTI-XmlWordSplitter.aspx</guid></item><item><title>Changes to the LIFTI API</title><link>http://www.goatly.net:80/2011/6/8/Changes-to-the-LIFTI-API.aspx</link><description>
&lt;blockquote&gt;
&lt;p&gt;This post relates to the breaking changes between version 0.4
and 0.5 of LIFTI. LIFTI is a full-text indexing library for .NET -
find out more on its &lt;a href="http://lifti.codeplex.com/" target="_blank"&gt;CodePlex site&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The latest release of LIFTI has several breaking changes that
&lt;strong&gt;will&lt;/strong&gt; affect you, so I wanted to take some time to
explain not only what they are, but why I made them. I'll start
with the what, then move onto the why.&lt;/p&gt;

&lt;h2&gt;No more constructor delegates&lt;/h2&gt;

&lt;p&gt;Previously when you wanted to construct a full text index,
updatable or otherwise, you would have had to provide a delegate
that was capable of taking the type of item in the index and
returning the text it should be indexed against, like this:&lt;/p&gt;

&lt;pre class="code"&gt;
var index = new FullTextIndex&amp;lt;Customer&amp;gt;(c =&amp;gt; c.Name);
&lt;/pre&gt;

&lt;p&gt;This is no longer the case - constructing an index is now as
simple as it can be:&lt;/p&gt;

&lt;pre class="code"&gt;
var index = new FullTextIndex&amp;lt;Customer&amp;gt;();
&lt;/pre&gt;

&lt;p&gt;If you have been using LIFTI you'll probably be aware that the
reason the constructor used to take a delegate was to provide some
of the Index methods with the text an item should be index against;
this leads me nicely onto the next change.&lt;/p&gt;

&lt;h2&gt;A rationalised set of Index methods&lt;/h2&gt;

&lt;p&gt;There used to be 5 Index methods - these have been reduced to 4,
which can be broken into two categories, &lt;em&gt;indexing keys&lt;/em&gt; and
&lt;em&gt;indexing arbitrary classes&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;Indexing "keys" rather than "items"&lt;/h3&gt;

&lt;p&gt;It's often useful (and when it comes to using a persisted index,
just plain sensible) to store just a key to an item in the index.
That is to say, rather than storing a "Movie" class in the index,
just storing the customer ids, e.g. an integer. There are two Index
methods that support this:&lt;/p&gt;

&lt;pre class="code"&gt;
// Explicitly pass the key and text values
index.Index(movie.MovieId, movie.Description);
index.Index(movieId, description);

// Or you can index an enumerable of keys like this
var ids = new[] { 23, 44, 192 };
index.Index(ids, i =&amp;gt; LoadDescriptionForMovie(i));
&lt;/pre&gt;

&lt;h3&gt;Indexing arbitrary classes in the index&lt;/h3&gt;

&lt;p&gt;There are two Index methods on the IFullTextIndex interface that
you can use to index instances of Movie directly, should you so
wish:&lt;/p&gt;

&lt;pre class="code"&gt;
// Pass the movie instance and use delegates to extract the 
// relevant information
var movie = new Movie { MovieId = 1, Description = "Best movie ever!" };
index.Index(movie, m =&amp;gt; m.MovieId, m =&amp;gt; m.Description);

// The equivalent "index many":
var movies = new[] 
{
    new Movie { MovieId = 1, Description = "Best movie ever!" },
    new Movie { MovieId = 2, Description = "Worst movie ever!" }
};
index.Index(movies, m =&amp;gt; m.MovieId, m =&amp;gt; m.Description);
&lt;/pre&gt;

&lt;h2&gt;No more Reindex methods&lt;/h2&gt;

&lt;p&gt;I'm hoping you'll not miss them though. Instead, when you're
using an updatable index, either UpdatableFullTextIndex or
PersistedFullTextIndex, calls to any of the Index methods will
automatically remove the item from the index prior to indexing, if
it's already there.&lt;/p&gt;

&lt;h2&gt;Serialization namespace is gone&lt;/h2&gt;

&lt;p&gt;That's right, gone, along with all the serialization classes in
it. If you were using it, I really am sorry, but there were good
reasons to do so, and I think there are much better alternatives
now.&lt;/p&gt;

&lt;h2&gt;Ok, so why?&lt;/h2&gt;

&lt;p&gt;First up, I'll deal with the changes to the constructor and the
Index methods, because they are both closely related.&lt;/p&gt;

&lt;h3&gt;Constructors and Indexing&lt;/h3&gt;

&lt;p&gt;While I was writing the original serialization code (even before
the persisted full text index work) it became apparent that under
most circumstances it was going to be best to store a simple value
type (e.g. int) in the index, rather than an arbitrary class (e.g.
Customer). The reason for this was twofold:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Primitive types are just a lot easier to serialize - most of
the time LIFTI can handle primitive types without any
configuration.&lt;/li&gt;

&lt;li&gt;If you're serializing the full text index somewhere, the
chances are the classes are going to be persisted somewhere else,
probably a database of some sort. Persisting the classes in the
serialized index is a bad case of data duplication and things will
definitely get out of sync sooner or later.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Although it's possible, storing a simple id in the index doesn't
lend itself naturally to using a delegate to read out the related
text. It would usually mean having to call out to another method,
like this:&lt;/p&gt;

&lt;pre class="code"&gt;
var index = new FullTextIndex&amp;lt;int&amp;gt;(i =&amp;gt; GetTextForCustomerId(i));
&lt;/pre&gt;

&lt;p&gt;Ok, you could write it like this, but it feels even more
odd:&lt;/p&gt;

&lt;pre class="code"&gt;
var index = new FullTextIndex&amp;lt;int&amp;gt;(GetTextForCustomerId);
&lt;/pre&gt;

&lt;p&gt;Indeed, sometimes it may not even be possible to write a
delegate ahead of time to return the text for an id - you might
just have access to an id and a piece of text at the time it comes
to perform the indexing.&lt;/p&gt;

&lt;p&gt;Taking all this into account, hopefully it's fairly clear why I
decided to remove the delegate from the constructor and, because
some of the Index methods relied on there being a pre-defined way
of getting hold of the text for a key value, why it was necessary
to rationalise the Index methods.&lt;/p&gt;

&lt;p&gt;But couldn't I just have added a separate overload for the
constructor, or allow the delegate to be null? Well, yes, naturally
I could, and I tried it for a while, but I felt that it made the
API a bit more confusing. Some of the Index methods had to throw
exceptions at runtime if no delegate was provided upon construction
- not very nice at all. At least this way you know where you stand
- each and every Index method must be given enough information to
identify a key value and its associated text.&lt;/p&gt;

&lt;h3&gt;Getting rid of the Reindex methods&lt;/h3&gt;

&lt;p&gt;I did this primarily because I was a little uncomfortable just
throwing an exception up if an Index method was called and the key
already existed in the index - in some circumstances it felt like
this was the wrong behaviour. Realistically all this does is save
the use of API needing to check to see if item exists and adjust
their behaviour depending on the result.&lt;/p&gt;

&lt;h3&gt;Getting rid of old Serialization classes&lt;/h3&gt;

&lt;p&gt;The decision to do this influenced by a couple of factors. The
first was the fact that I had just implemented the persisted index,
which covers exactly what the old serialization code did with the
added benefit that you don't need to remember to serialize the
index when your application exits and you don't have to manually
deserialize it when the application starts. The deserialization
point is particularly interesting; the old serialization process
required that the entire index was loaded into memory before it
could be used - the persisted index lazy loads parts of the index
as it is accessed, which for large indexes can make it available
for use in a much shorter space of time. I'll cover more on this
lazy loading in a later post.&lt;/p&gt;

&lt;p&gt;Another factor was that in order to support the old
serialization process I had to expose elements of the full text
index class that I wasn't really happy doing. For example in 0.4
the RootNode property of the IFullTextIndex interface had a setter
- allowing the root node to be changed this way was a bit scary and
had big implications for the persisted index implementation. There
were probably other ways around this, but this combined with the
first point made the decision fairly easy.&lt;/p&gt;

&lt;h2&gt;Wrap up&lt;/h2&gt;

&lt;p&gt;This is the first time I have had to make significant breaking
changes to the API - I'm not going to promise it's the last, but I
think it is approaching something that resembles a stable
state.&lt;/p&gt;

&lt;p&gt;Some of these changes may be controversial, and I'm sure that
other people will have differing opinions on how it should have
been done. I'd be really interested to hear if the changes have
been significantly problematic for you - either leave me a comment
here, or start a thread on the &lt;a href="http://lifti.codeplex.com/discussions" target="_blank"&gt;discussions board&lt;/a&gt;. I want to hear all feedback,
positive or negative!&lt;/p&gt;
</description><pubDate>Wed, 08 Jun 2011 00:00:00 GMT</pubDate><guid isPermaLink="true">http://www.goatly.net:80/2011/6/8/Changes-to-the-LIFTI-API.aspx</guid></item></channel></rss>