Installing jekyll-import and jekyll On Windows

I already had an updated version of Ruby installed, thanks to Chocolatey, so I went ahead and ran:

C:\>gem install jekyll-import
ERROR: Could not find a valid gem 'jekyll-import' (>= 0), here is why:
Unable to download data from https://rubygems.org/ - 
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (https://api.rubygems.org/latest_specs.4.8.gz)

Clearly something to do with certificates and I had to download the .PEM file from http://curl.haxx.se/ca/cacert.pem and run the following command in a command prompt:

C:\>set SSL_CERT_FILE=C:\path-to-pem-file\cacert.pem

Let’s try installing the gem again.

C:\>gem install jekyll-import
Fetching: fast-stemmer-1.0.2.gem (100%)
ERROR:  Error installing jekyll-import:
        The 'fast-stemmer' native gem requires installed build tools.

Please update your PATH to include build tools or download the DevKit
from 'http://rubyinstaller.org/downloads' and follow the instructions
at 'http://github.com/oneclick/rubyinstaller/wiki/Development-Kit'

Ok, we got past the certificate error, but now we’ll need to install the Ruby DevKit. Chocolatey can help us with this:

C:\>cinst ruby2.devkit

When installed I ran this to update the PATH:

C:\>c:\tools\DevKit2\devkitvars.bat
Adding the DevKit to PATH...

Finally I was able to install the jekyll-import gem successfully and I had exported some old blog posts from wordpress.com which I wanted to import into Jekyll for testing purposes.

C:\>ruby -rubygems -e "require 'jekyll-import'; JekyllImport::Importers::WordpressDotCom.run({ 'source' => 'wordpress.xml', 'no_fetch_images' => false, 'assets_folder' => 'assets' })"


Whoops! Looks like you need to install 'hpricot' before you can use this importer.

If you're using bundler:
  1. Add 'gem "hpricot"' to your Gemfile
  2. Run 'bundle install'

Fair enough, they mentioned this in the docs, so I ran:

C:\>gem install hpricot

I was then able to import the old blog posts successfully:

Downloading images for foo - bar
  http://foo.files.wordpress.com/2010/03/bar.png
    OK!
Imported 4 posts
Imported 2 attachments

Installing Jekyll afterwards was straightforward:

C:\>gem install jekyll
Successfully installed jekyll-2.5.3
Parsing documentation for jekyll-2.5.3
Done installing documentation for jekyll after 1 seconds
1 gem installed

Design-time support for XAML files in class libraries

One thing you’ll experience if you split your WPF/Silverlight applications into modules, for instance by following the Composite Application Guidance for WPF and Silverlight, is the lack of design-time support for the modules which are split out into separate class libraries. In Expression Blend 3, you will only be able to edit the modules in XAML view, which is kind of annoying, since you’ll be missing out on many of the benefits the design view can offer.

Luckily there’s something you can do to remedy this situation. The solution is easy, all you’ll have to do is to add one line in your module’s project file. Open the file in Notepad and add

<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

in the first property group. Expression Blend should now be able to load the design surface for you!

Package 'Microsoft.VisualStudio.Xaml' has failed to load properly

I just wanted to give you a heads up, in case you experience the same problem I faced yesterday. After installing the Windows Phone 7 developer tools Visual Studio 2008 suddenly started giving me “Package Load Failure” errors when opening one of my WPF projects.

Here’s what the error message looks like:

Package Load Failure
Package 'Microsoft.VisualStudio.Xaml' has failed to load properly ( GUID = {E58C2A8B-BCC4-4559-AD59-D62EB6D58A22} ). Please contact package vendor for assistance. Application restart is recommended, due to possible environment corruption. Would you like to disable loading this package in the future? You may use 'devenv /resetskippkgs' to re-enable package loading.

The problem is related to the order in which you install the Express SKU and the Standard SKU, which can leave the system in a broken state.

To fix this problem you can run the standalone Visual Studio 2008 Service Pack 1 installer.

Entity Framework – View generated SQL queries

I’ve created an example that uses the “Orders” and “Order_Details” tables in the Northwind database, to show how you can easily view the SQL queries that are being generated by the Entity Framework. In order to simplify this I’ve created a static class called “ExtensionMethods” which has two extension methods, both named “SqlQuery”.

The code

In the first query I’m retrieving the orders that have been shipped  to Norway. In this case it will return the matching orders as IQueryable<Order>, since this table is on the “one” end of the relationship with “Order_Details”.

In the second query I want the order details of order 10248. Since the order details table is on the “many” end of the relationship with “Orders” it will return the order details as EntityCollection<Order_Detail>.

We have to treat these two types differently in order to extract the SQL query generated by the Entity Framework. How this can be done is shown in the 2nd snippet below.

static void Main()
{
    using (NorthwindEntities db = new NorthwindEntities())
    {
        IQueryable<Order> orders = db.Orders
            .Where(x => x.ShipCountry == "Norway");

        Console.WriteLine("Generated SQL query: " +
            Environment.NewLine +
            orders.SqlQuery() +
            Environment.NewLine);

        EntityCollection<Order_Detail> orderDetails = db.Orders
            .Where(x => x.OrderID == 10248)
            .First()
            .Order_Details;

        Console.WriteLine("Generated SQL query: " +
            Environment.NewLine +
            orderDetails.SqlQuery());
    }
}

 

And here are the extension methods I’ve created, which return the generated SQL queries for data of IQueryable<T> and EntityCollection<T>, respectively.

public static class ExtensionMethods
{
    public static string SqlQuery<T>(this IQueryable<T> source)
    {
        ObjectQuery<T> objectQuery = source as ObjectQuery<T>;

        if (objectQuery != null)
            return objectQuery.ToTraceString();

        return string.Empty;
    }

    public static string SqlQuery<T>(this EntityCollection<T> source) where T : class
    {
        ObjectQuery<T> objectQuery = source.CreateSourceQuery();

        return objectQuery.ToTraceString();
    }
}

 

And here’s the output:

ef_sql

Enjoy!

Getting started with query notifications

The SqlDependency class was introduced in .NET 2.0, but still there are many developers not aware of this functionality, or many not using it because it can be somewhat cumbersome to make it work properly.

This class gives you the ability to create a dependency between your application and SQL server 2005/2008, which in turn will notify your application whenever the result set of your query changes. This is ideal for scenarios that involve caching or where you normally would use some sort of polling mechanism.

It’s worth that the applications that will benefit the most from query notifications are those that mostly read data and where updates are infrequent. This is because query notification introduces an overhead, as it has to check for active subscribers, and raise notifications, whenever the table data is altered.

Database permissions

This is the part that causes most of the trouble for people trying to get query notifications working. It can be very hard to troubleshoot what’s wrong, because quite often you get no error message at all, stating what the possible cause is. The SQL statements below should make sure you’re good to go.

Open up your query window and run the following command, to make sure you’re working against the correct database:

USE DatabaseName

The first thing you need to check is that the service broker on your SQL server is running. This is is done by running the command below, which should return “1”.

SELECT is_broker_enabled FROM sys.databases where name = 'DatabaseName'

If the command above returned “0” you need to run the command below, then rerun the command above to make sure it now returns “1”:

ALTER DATABASE DatabaseName SET ENABLE_BROKER

Then you need to give the database user you’re going to use in your application some permissions, to allow it to create the needed procedure, queue and service:

GRANT CREATE PROCEDURE TO DatabaseUser
GRANT CREATE QUEUE TO DatabaseUser
GRANT CREATE SERVICE TO DatabaseUser

You then need to allow your user to be able to subscribe to query notifications, by running the following command. Make sure that the database user is the same as you’re specifying in your connection string.

GRANT SUBSCRIBE QUERY NOTIFICATIONS TO DatabaseUser

To successfully register a notification, the database user needs SELECT privileges on the table that it’s trying to query. You only need to do this if your login isn’t sysadmin or db_owner. The schema value below will for the majority of people be “dbo”.

GRANT SELECT ON OBJECT::Schema.TableName TO DatabaseUser

The last permission you will have to give the database user is to allow it to receive notifications sent to the message queue by SQL server:

GRANT RECEIVE ON QueryNotificationErrorsQueue TO DatabaseUser

To make sure that all the permissions have been granted, you can run the following command in the query window:

exec sp_helprotect NULL, 'DatabaseUser'

Some code please!

In this example I’m going to create a simple console application that will receive query notifications. Exception handling is not implemented in this example, to keep it simple.

The first thing we’re doing is checking that we’re allowed to request notifications. If we’re allowed to do that we start listening for notifications from the SQL server specified in the connection string. We then register our dependency, which is done by specifying an SQL query and associating an instance of the SqlDependency class with our SqlCommand instance. The code is shown below…

static void Main()
{
    if (CanRequestNotifications())
    {
        SqlDependency.Start(ConnectionString);

        Console.WriteLine("Started the listener...");

        RegisterDependency();

        Console.WriteLine("Press enter to quit...");
        Console.ReadLine();

        Console.WriteLine("Stopping the listener...");

        SqlDependency.Stop(ConnectionString);
    }
    else
        Console.WriteLine("Not allowed to request notifications!");
}

This method will return true if all the correct permissions are set.

private static bool CanRequestNotifications()
{
    SqlClientPermission permission = new SqlClientPermission(PermissionState.Unrestricted);
    try
    {
        permission.Demand();
        return true;
    }
    catch (Exception)
    {
        return false;
    }
}

This method will register the dependency with the SQL server and hook up an event handler, which will be invoked whenever the result set of the SQL query you’ve specified has changed. There as some restrictions on what type of queries you can specify, read more about the limitations here.

private static void RegisterDependency()
{
    using (SqlConnection connection = new SqlConnection(ConnectionString))
    {
        SqlCommand command = new SqlCommand("select Id from dbo.table", connection) { Notification = null };

        SqlDependency dependency = new SqlDependency(command);
        dependency.OnChange += DependencyOnChange;

        connection.Open();

        SqlDataReader dr = command.ExecuteReader(CommandBehavior.CloseConnection);

        if (dr != null)
        {
            // Cache or display the data if you need to

            dr.Close();
        }
    }
}

This is the method that will be invoked whenever the result set of your query has changed. As you can see we need to unhook the event handler and then register a new one.

A query notification will be sent if any of the following events occur:

  • Rows contained in the query results may have changed.
  • The subscription expires.
  • The server restarts.
  • The query notification subscription could not be created (for example, the SELECT statement does not conform to the requirements specified in Creating a Query for Notification.
  • The server is heavily loaded.
  • Objects that the subscription depends on are dropped or modified.
private static void DependencyOnChange(object sender, SqlNotificationEventArgs e)
{
    SqlDependency dependency = (SqlDependency)sender;
    dependency.OnChange -= DependencyOnChange;

    Console.WriteLine(DateTime.Now.ToLongTimeString() +
        " Info:" + e.Info +
        " Type:" + e.Type +
        " Source:" + e.Source);

    RegisterDependency();
}

That’s it! You should now be able to enjoy the benefits of query notification in your own applications!