Entity Framework–> Change Database

I was working with Entity Frameworks over the weekend when I ran into some sloppy programming on Microsoft’s part.  I made a project that uses Entity Frameworks to connection to Northwind.  I then added method to change the database at runtime like so:

public class NorthwindFactory
{
    public static void ChangeDatabase(String newDatabaseName)
    {
        using (NorthwindEntities entities = new NorthwindEntities())
        {
            entities.Connection.ChangeDatabase(newDatabaseName);
        }
    }
}

When I checked out intellisense on the ChangeDatabase method, there was nothing to indicate anything unusual.

image

When I invoked the method, I got the following exception:

image

Sure enough, when I go to MSDN help online, ChangeDatabase() is not supported in 4.5 and 4.0, but it is supported in 3.5. 

image

This is a clear violation of the Liskov Substitution Principle.  It is a also sloppy – they could have marked it obsolete or, at least, changed the XML code comments to reflect the fact that it is not supported.  Instead, they left it up to the developer to get the exception the first time s/he invokes it.

So instead of using the ChangeDatabase() method, I needed to use the SqlConnectionStringBuilder and EntityConnectionStringBuilder like so:

SqlConnectionStringBuilder sqlConnectionStringBuilder = 
    new SqlConnectionStringBuilder();
sqlConnectionStringBuilder.DataSource = ".";
sqlConnectionStringBuilder.InitialCatalog = newDatabaseName;
sqlConnectionStringBuilder.IntegratedSecurity = true;

EntityConnectionStringBuilder entityConnectionStringBuilder = 
    new EntityConnectionStringBuilder();
entityConnectionStringBuilder.Metadata = 
    @"res://*/NorthwindModel.csdl|res://*/NorthwindModel.ssdl|res://*/NorthwindModel.msl";
entityConnectionStringBuilder.Provider = "System.Data.SqlClient";
entityConnectionStringBuilder.ProviderConnectionString = 
    sqlConnectionStringBuilder.ConnectionString;

The problem is that I can’t use that entityConnectionStringBuilder inside of the using block of the Entity that I want to change:

image

So to switch databases, I have to drop the “using” statement.  The below code snippet works

NorthwindEntities entities = new NorthwindEntities();
SqlConnectionStringBuilder sqlConnectionStringBuilder = 
    new SqlConnectionStringBuilder();
sqlConnectionStringBuilder.DataSource = ".";
sqlConnectionStringBuilder.InitialCatalog = newDatabaseName;
sqlConnectionStringBuilder.IntegratedSecurity = true;

EntityConnectionStringBuilder entityConnectionStringBuilder = 
    new EntityConnectionStringBuilder();
entityConnectionStringBuilder.Metadata = 
    @"res://*/NorthwindModel.csdl|res://*/NorthwindModel.ssdl|res://*/NorthwindModel.msl";
entityConnectionStringBuilder.Provider = "System.Data.SqlClient";
entityConnectionStringBuilder.ProviderConnectionString = 
    sqlConnectionStringBuilder.ConnectionString;

entities = new NorthwindEntities(entityConnectionStringBuilder.ConnectionString);

I am not sure Microsoft thought this one through…

Advertisements

Consuming JSON from a C# Project

I was thinking about an app that I have wanted to write for a while.  Part of the application uses weather data.  Since I have been using weather underground since forever (Go Blue), that seemed like a natural place to start.  I hopped over to wunderground and sure enough, at the bottom of the page is a link for consuming its API. 

image

Following the Weather API for Developers – JSON link, I signed up for a free developer account.  Within minutes I got my API key and I was ready to start looking for the data I was interested in for my application. I first went to the documentation page, I started with the current conditions for a city example:

http://api.wunderground.com/api/axxxxxx/conditions/q/CA/San_Francisco.json

I then switched out the state/city criteria with my zip code:

http://api.wunderground.com/api/axxxxxxxx/conditions/q/27519.json

Sure enough, data is getting returned.

image

Now that I have a source of data, I need a way to consume the data using Visual Studio.  I fired up a Console project just to see how difficult it would be to consume.  I put in a typical webrequest/response:

Uri uri = new Uri(@"http://api.wunderground.com/api/xxxxxxxx/conditions/q/27519.json");
WebRequest webRequest = WebRequest.Create(uri);
WebResponse response = webRequest.GetResponse();
StreamReader streamReader = new StreamReader(response.GetResponseStream());
String responseData = streamReader.ReadToEnd();
Console.WriteLine(responseData);

Sure enough, I am getting the data back:

image

The next step is to parse this string so I can do something useful with it.  Fortunately, I was coding this solution during a meeting of Cary’s Technology Task Force and I was sitting next to an OData/JSON expert: Ian Cillay .  Ian told me that to parse Json from VS, I needed to get Newtonsoft’s Json.NET framework because MSFT has essentially given up on the parsing and is deferring everything to NewtonSoft.  Once I had that installed via NuGet, I the realized I still needed a class pre-defined to populate from the Json feed.  I fired up a new class with a couple of properties:

public class WeatherData
{
    public String pressue_mb { get; set; }
    public String pressume_in { get; set; }
    public String pressure_trend { get; set; }
    public String relative_humidity { get; set; }
}

I then coded up line to use that Json library to put the data from the response string into an instantiated class:

var outObject = JsonConvert.DeserializeObject<WeatherData>(responseData);

However, when I ran it, nothing was getting populated.

image

Ian told me that my simple class did not reflect the actual Json.  Stumped (and still hating Json), I then stumbled across this site.  Sure enough  it was like SVCUTIL.exe for Json.  I got the classes created for me

image

and I then could consume the data like this:

var outObject = JsonConvert.DeserializeObject<RootObject>(responseData);

and the output is

image

Wahoo!  I will use the Visual Studio’s External Tools Feature to generate classes for me on the fly:

image

RDU Code Camp

TriNug put on an awesome codecamp over the weekend.  I presented programming the Kinect.  There was about 20 people in my session (more than I expected) and we had a great time going through some of the basic (and way cool) features of the Kinect API.  I hope to see some really neat projects at future TriNug events using the Kinect.

My side deck and code samples are on TriNug’s wiki found here.

Proper Casing Of Proper Names

I was consuming an external API that was returning people’s first names.  The problem was that the names were coming back all caps (eg: “GILLIGAN”).  I wanted to convert that into the proper case (eg: “Gillian”).  In the past, I would call ToLower() of the string and then take the first character of a substring and make it Upper().  To protect myself in case there was several words in the name(eg: MARY ANN), I would also need to split on any spaces and loop through the array doing my Upper/Lower functions.  The code would look something like this:

static void WrongWay(String name)
{
    String tempWord = String.Empty;
    String firstLetter = String.Empty;
    String restOfWord = String.Empty;
    StringBuilder stringBuilder = new StringBuilder();

    String[] splitName = name.Split(' ');
    foreach (String word in splitName)
    {
        tempWord = word.ToLower();
        firstLetter = tempWord.Substring(0, 1);
        firstLetter = firstLetter.ToUpper();
        restOfWord = tempWord.Substring(1, tempWord.Length-1);
        stringBuilder.Append(firstLetter);
        stringBuilder.Append(restOfWord);
    }
    Console.WriteLine(String.Format("Was = {0} Now = {1}", name, stringBuilder.ToString()));
}

And the output looks like this:

image

I hate this solution for a couple of reasons:

  • It smells like Kludgy code
  • It is Kludgy code
  • It does not account for people with single letter names
  • It does not account for internationalism and different languages that use different glyphs

I thought to myself – there must be a better way and since Microsoft has lots of smart people, they might have done something like this already.

My first stop was the String.ToLower() overload.  I pumped in the different cultures (Current and CurrentUI):

static void WriteNames(String name)
{
    CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
    CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture;

    Console.WriteLine(String.Format("ToLower = {0}",name.ToLower()));
    Console.WriteLine(String.Format("ToUpperWithCurrentCulture = {0}", name.ToLower(currentCulture)));
    Console.WriteLine(String.Format("ToUpperWithCurrentUICulture = {0}", name.ToLower(currentUICulture)));
}

Alas, it did not work:

image

ToUpper() had the same (non) effect.

I then thought “Hey, maybe I should check MSDN or Stackoverflow”.  Sure enough, I ran into this page.  Without reading the entire page (who does that?)  I jammed in this line of code,

Console.WriteLine(String.Format("currentCulture.TextInfo.ToTitleCase using Upper = {0}", 
    currentCulture.TextInfo.ToTitleCase(name)));

but I got the same result:

image

 

I then went back and read the entire MSDN page.  I changed my code to this (note the ToLower())

Console.WriteLine(String.Format("currentCulture.TextInfo.ToTitleCase using Lower = {0}",
    currentCulture.TextInfo.ToTitleCase(name.ToLower())));

Sure enough:

image

Not only that, it works for multiple words:

image

Not only that, it handles middle initials!

image

Alas, it does not handle suffixes:

image

Still, that function gives you plenty out of the box.  I am very excited (OK, mildly excited) about this new find….

Using Pointers In Managed Code

I am getting ready for my Kinect presentation at RDU’s code camp.  One of the techniques that you have to absolutely use with the tidal wave of data that the Kinect sends you is pointers.  For example, I have some code that is straight from this book where I turn the video image from the the Kinect ColorSensor a darker shade of blue.

In a default WPF application, I added the following class-level variables:

KinectSensor kinectSensor = null;
WriteableBitmap colorImageBitmap = null;
Byte[] colorData = null;

I then wired up the Kinect:

kinectSensor = KinectSensor.KinectSensors[0];
kinectSensor.ColorStream.Enable();
kinectSensor.ColorFrameReady += new EventHandler<ColorImageFrameReadyEventArgs>(kinectSensor_ColorFrameReady);
kinectSensor.Start();

I then added the following code to the event handler as the video frames come in (30 per second, each frame about 1.5 megs):

if (colorImageFrame != null)
{
    if (colorImageBitmap == null)
    {
        colorImageBitmap = new WriteableBitmap(
            colorImageFrame.Width,
            colorImageFrame.Height,
            96, 96,
            PixelFormats.Bgr32,
            null);
        this.kinectImage.Source = colorImageBitmap;
    }
    if (colorData == null)
    {
        colorData = new Byte[colorImageFrame.PixelDataLength];
    }

    colorImageFrame.CopyPixelDataTo(colorData);
    
   
    Int32 newColor = 0;
    for (int i = 0; i < colorData.Length; i = i + 4)
    {
        Int32 oldColor = colorData[i];
        newColor = (Int32)colorData[i] + 50;
        if (newColor > 255)
        {
            newColor = 255;
        }
        colorData[i] = (byte)newColor;
    }  
  

    colorImageBitmap.WritePixels(
        new Int32Rect(0, 0, colorImageFrame.Width, colorImageFrame.Height),
        colorData,
        colorImageFrame.Width * colorImageFrame.BytesPerPixel, 0);
    
}

This code works – but it gets too slow when using an under powered computer.  To use pointers, I first needed to mark my project as unsafe:

image

I then added the unsafe keyword to the event handler:

unsafe void kinectSensor_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)

And finally, I replaced the managed loop with a loop that uses pointers:

int noOfPixelBytes = colorData.Length;
fixed (byte* imageBase = colorData)
{
    byte* imagePosition = imageBase;
    byte* imageEnd = imageBase + noOfPixelBytes;

    Int32 newColor = 0;
    while (imagePosition != imageEnd)
    {
        newColor = *imagePosition + 50;
        if (newColor > 255)
        {
            newColor = 255;
        }
        *imagePosition = (byte)newColor;
        imagePosition += 4;
    }
}

This speed things up considerably.  A couple of things to note:

The fixed keyword pins the location of imageBase to 1 location so the garbage collector doesn’t move it around.  Also, note that I refer the to value of the current byte via imagePosition* (*imagePosition = (byte)newColor) – when I want to move 4 bytes over, I increment the imagePosition (imagePosition += 4)

I am looking forward to Saturday  hopefully this presentation will go off without a hitch…