Wednesday, July 24, 2013

C# is Case Sensitive...Right?

Well...yes, of course.  It's well known that C# is case sensitive(interesting discussion on this can be found here).  If you declare a variable like this...

string name = "John";

...it will be different than a variable declared this way...

string nAme = "Smith";

One of the easiest ways to tell if your variables are spelled correctly is to try to compile your project. If your case is off, you'll get an exception at compile time and your code will not run at all. This is different from VB.Net, where variable names are not case sensitive in the VB.Net IDE.

Dim name as string ="John"

and

nAME as string="Smith"

is allowed because the  VB.Net IDE ignores the case difference between "name" and "nAME". In VB.Net land, they are the same variable and you can't declare a variable with the same name in the same scope more than once.  Note that the IDE allows you to get away with different cases in VB.Net.  The compiler/CLR take care of case issues later(more here).

But while I was using Dapper, I noticed something odd.  Sometimes the case between a class type<T> and the table column matched and sometimes they didn't but Dapper didn't seem to care at all.  But if I called the .Query method without a <T> parameter, then case did matter.

If you call .Query in Dapper without a <T> parameter the method will return IEnumerable of type dynamic.  I didn't know much about dynamic at the time but I assumed this would let you play fast and loose with property names.  But that's not what happens.  Dapper allows mis-matched case when referencing a Type property but if you don't specify a Type and you are dealing with IEnumerable of dynamic types, you have to match case or you get run time exceptions (not compile time exceptions).  This is counter intuitive but that was obviously how it worked.

In this example I specify Type:

List players = cn.Query<Player>("select * from player");

Console.Writeline("Player ID: {0}",players.FirstOrDefault().PlayerID);

This works fine even though the column name that the PlayerID is referencing is "playerID".  Column names are not case sensitive in MS SQL, but we're in that twilight zone where  database types are mapped to CLR types.  On the CLR side case sensitivity is going to make itself known.  But it doesn't matter here.  I can rename the column name to pLaYeRiD and it will still match to the property name PlayerID in my Player object.

But in this example, case does matter even though we are returning IEnumerable of dynamic.

var players = cn.Query("select * from player");

Console.Writeline("Player ID: {0}",players.FirstOrDefault().PlayerID);

This will throw a run-time exception Microsoft.CSharp.RuntimeBinder.RuntimeBinderException with the text "Could not match up class property with object property."

Weird huh?  Specify a Type and you can play fast and loose with the bindings.  Don't specify a Type, go dynamic, and you have to match the property name case exactly to the the case of the column returned in the record set.

The thing to keep in mind with the dynamic "type" is that it's not really a type.  There is still an underlying type that's the real type.  When you use the dynamic type for a variable, you are saying to the compiler, "I got this.  You don't need to check type whenever you see this variable during compile time."  Does this sound a lot like the object type?  It works exactly the same way in many circumstances.  In fact, dynamic only exists at compile time.  At run time it's converted into type object.  (Read about it here on MSDN).

So what's Dapper doing behind the scenes here?  Since it's an open source project we don't have to guess, we can look at the source code.  This link will show the source code for how Dapper maps a Typed query.  The part we really care about is in the GetMember method.  If you step through that you'll see how the property names of the class are matched up with field/column names from the returned record set.  The matching is done with the null coalescing operator:


var property = _properties.FirstOrDefault(p => string.Equals(p.Name, columnName, StringComparison.Ordinal))
               ?? _properties.FirstOrDefault(p => string.Equals(p.Name, columnName, StringComparison.OrdinalIgnoreCase));

StringComparison.Ordinal means to compare the strings by comparing a code for each char in the string.  It's fast but culture dependent.  Remember that Dapper was built for speed, so it reasons they chose speed over the ability to by culture independent.  If it finds a match there, great.  If it doesn't then it does the same comparison but with StringComparison.OrdinalIgnoreCase.  OrdinalIgnoreCase converts each char in both strings to all upper case and then checks for a match.  That's why you don't have to match case when comparing properties of a Type to columns in a returned record set.  If it doesn't find a perfect match the first time, it coverts everything to upper case and checks again.  I suspect matching case on both sides would result in slightly faster return times.  Once a match is made an object of type SimpleObjectMap is returned.

So what about the dynamic side of things?  It's a lot more straightforward...and convoluted.  Lines 1635-1643 show where Dapper loops through the columns in the result set and makes a DapperTable filled with the names of the columns.  If you step through the code you'll see that these are in turn converted to a collection of DapperRow and this is what is returned to the calling method undercover of dynamic.  The DapperRow class builds "properties" that have the same name and type as the column returned from the database.  Since these are properties, they have to be referred to with matching case.  I could spend a few more posts just on the DapperRow class but that's the gist of how it works.

So case sensitivity holds up like it is supposed to in C#.  If Dapper has a Type to work with in addition to a set of columns, it can make mappings for you even if you get the case wrong.  If you are leaving it up to Dapper to return  the result and and work without a column map you have to make sure the case is right for each property.  Intellisense won't help you.







Saturday, July 13, 2013

Screencasting on a Budget

Scott Hanselman has a great post about making quality screencasts.  If you want to get into the screencasting thing, go read it.  If you are able to buy the recommended software and hardware that Scott recommends, great!  No need for you to read further.  But if you are on a budget or you want to make sure screen casting is really for you before you sink a lot of money into it, then read on...

  1. Don't use your computer/laptop microphone.  You're going to need a new microphone.  I didn't have $100+ (or $300+) to spend on a mic, so I bought the Samson Go Mic (on Amazon) for $39.99.  It's a USB mic (which is important) and it's very highly reviewed.  It has worked great for me both for screen casts and for interviews for my linguistics class.  This is the most expensive thing I've purchased for screen casting.
  2. Download Audacity.  You need a way to modify the sound from your screen casts.  Audacity is free.  Learn how to insert silence, add a music track, fade in, fade and most importantly, Noise Removal.
  3. Download Screencast O Matic.  You can use the free version but go ahead and spend the money on the pro version, it's $15 a year.  You are going to need the tools in the pro version to cut out your mistakes, add transitions (like dissolves) and most importantly, export and and import your audio track (which you cleaned up using Audacity).

That's really all you need.  Total cost is $45 and some change.  When you are recording be sure to turn off any fans, window A/C units, mobile phones, tablets and any program that might automatically pop up a notification or make a sound. If you have any three year olds in the house, you might want to wait until they are asleep.

Once you've exported your screen cast to a video file, you can upload it to You Tube for free, or you can use Vimeo.  I suggest you check out Vimeo, they have a basic plan that's free.  I decided to use Vimeo Plus which costs me $9.99/month.  So far I've been very pleased with the service.  If you want to keep costs low at the start, stay with You Tube but you will probably see the need for more than the free service that You Tube offers if you continue screen casting. There are a number of comparison articles on Vimeo vs You Tube to help you decide.

Friday, July 12, 2013

Getting Started With Dapper Part 3

     In part three I cover how to use alternate constructors for types used with Dapper. In parts 1 & 2 I used the default parameterless constructor but that doesn't work in every situation.

     Dapper can also make use of a constructor that matches the type and field names returned in a recordset in addition to completely custom constructors that don't mach up to returned recordsets.

     Lastly, I cover how to use a custom constructor and initialize a property during the Dapper mapping using Ling and a simple lambda expression.


Intro To Dapper - Part 3 from Jon Wear on Vimeo.

Source code: https://github.com/genghisjahn/DapperIntroPt1/archive/Pt3.zip