Tuesday, November 25, 2008

Making custom changes in LINQ-to-SQL designer

This post describes a scenario I encountered recently that would require making custom changes in the LINQ-to-SQL designer.

Even given that the Microsoft rumor-mill has tagged LINQ-to-SQL as terminal given the rise of LINQ-to-Entity, I still find LINQ-to-SQL useful for those non-enterprise solutions. As many developers know, the LINQ-to-SQL class designer doesn’t provide much automated support for keeping your database schema up-to-date with the class designer objects (tables, relationships, etc.)

I haven’t found this to be a huge issue since I work around this limitation by deleting and re-adding tables (which automatically updates the dbml code). I’ve steered clear of making any custom changes through the designer so I can perform this simple work around.

Recently I ran into an issue that makes me want to make manual changes in the designer. It has to do to the way the relationship property names are generated. Let’s look at an example.

Consider you have a table named Grades that represents school grades like 1, 2, 3, and so forth. Now assume you have another table named Worksheets that represents individual worksheets for each school grade. This is a typical one-to-many relationship. Two of the Worksheets columns are StoreGrade (where a PDF worksheet is stored on disk) and DisplayGrade (which grade to display this worksheet for). This allows a worksheet to be reused for 4th grade even though it is stored in the 3rd grade folder. The StoreGrade and DisplayGrade are foreign keys of the Grades table.

When using the LINQ-to-SQL designer, the above scenario will create a Grade object will two properties called Worksheets and Worksheets1. When using intellisense, it really isn’t possible to know which of these properties is for StoreGrade and which is for DisplayGrade. It is possible to change the property names created by using the designer properties for each relationship, but that would mean I lose the ability to delete/re-add a table with ease.

I’m continuing to hold off making custom designer changes, but this is one scenario I’ve run across that gives a reason to make custom changes via the LINQ-to-SQL designer.

Saturday, November 8, 2008

Measuring Stability and Abstractness

I've always felt that a proper Object-Oriented design must be focused on package and class relationships, and that those relationships should be loosely coupled.

Bob Martin wrote a book back in 1995 called Designing Object-Oriented C++ Applications Using the Booch Method. Chapter 3 of this book explained how to design a loosely coupled architecture based on cohesion and closure. Then in 2006 Bob and his son wrote Agile Principles, Patterns, and Practices in C#. Chapter 28 of this book revisited the topic of loosely coupled architectures.

I have always felt that this topic is crucial to both architecture and design of Object-Oriented solutions, and thus I often revisit the chapters from these books. I finally decided to encapsulate Bob's content into a single page diagram (taken from the second book).

Click here to get it!

Keep this single-page diagram near and dear to your heart...and read Bob's second book, twice.

Friday, November 7, 2008

Visual Studio macro to insert curly braces

I think the most frequently used set of keystrokes I use in development is the process of inserting two curly braces with a blank line in between them.

I found the following Visual Studio macro once on the Internet. You can add this to your list of Visual Studio macros, then use the keyboard configuration to assign it to a keystroke. I've assigned the macro so that when I press Shift-Return, it inserts two curly braces, a blank line in between them, then places the cursor indented on the blank line...ready to type in a statement. I use this keystroke constantly in development.

The macro works fine in both Visual Studio 2005 and 2008.

Sub InsertCurlies()
DTE.ActiveDocument.Selection.NewLine()
DTE.ActiveDocument.Selection.Text = "{"
DTE.ActiveDocument.Selection.NewLine()
DTE.ActiveDocument.Selection.Text = "}"
DTE.ActiveDocument.Selection.LineUp()
DTE.ActiveDocument.Selection.NewLine()
End Sub

Using LINQ's ToLookup

Often times you have a set of data and want to process the data in sets based on some property of the data. For example, you may want to process all employee records based on what state the employee lives in (presumably for tax purposes).

To organize the employees, we need something like a .NET dictionary class, but be able to store multiple employees per key (i.e. state). A dictionary only stores a single object per key so we're out of luck using that class.

This is where the LINQ ToLookup and GroupBy operators come to the rescue. ToLookup is a non-deferred operator and GroupBy is a deferred operator. The example below illustrates how ToLookup can be used to process employee objects, together, based on what state the employee lives in. The GroupBy is basically the same thing, but the data is grouped during enumeration because of its deferred nature.

private class Employee
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string StateAbbr { get; set; }
}

static void Main(string[] args)
{
new Program().Run(args);
}

private void Run(string[] args)
{
List<Employee> employees = new List<Employee>
{
new Employee { ID = 1, LastName = "Scott", FirstName = "Michael", StateAbbr = "CO" },
new Employee { ID = 1, LastName = "Smoe", FirstName = "Joe", StateAbbr = "CA" },
new Employee { ID = 1, LastName = "Lampton", FirstName = "Todd", StateAbbr = "CO" },
new Employee { ID = 1, LastName = "Morgan", FirstName = "Jared", StateAbbr = "WA" },
new Employee { ID = 1, LastName = "Smart", FirstName = "Laura", StateAbbr = "ID" },
new Employee { ID = 1, LastName = "Seashell", FirstName = "Sally", StateAbbr = "CO" },
};

ILookup<string, Employee> folksByState = employees
.ToLookup(e => e.StateAbbr);

foreach (IGrouping<string, Employee> stateGroup in folksByState)
{
Console.WriteLine("\nState: {0}", stateGroup.Key);
foreach (Employee e in stateGroup)
{
Console.WriteLine("{0}, {1}, {2}", e.LastName, e.FirstName, e.ID);
}
}
}

Sunday, November 2, 2008

Install Windows Media Player 11 on Windows Server 2003 SP2

I finally found a method that actually works to install Windows Media Player on Windows Server 2003 SP2. I've executed these instructions several times on a VPC, then on my normal server and it was easy. Works great!

1) Download the Windows Media Player 11 setup file and save to disk (e.g. wmp11-windowsxp-x86-enu.exe).

2) Run the setup file.

3) You should see if a Validation Checker dialog. Just leave this dialog box displayed this without clicking any of the buttons.

4) Search your hard drive for the file "wmp11.exe". Once found, use Windows Explorer and go to the directory where this file resides.

5) Copy all the files from this directory to another temporary directory, then close the Validation Checker dialog.

6) Use Windows Explorer and go to the temporary directory you created.

7) Right-click and change Properties on the following files; set Run in Compatibility Mode (on the Compatibility Tab) to Windows XP:

umdf.exe
wmfdist11.exe
wmdbexport.exe
wmp11.exe

8) Run wmfdist11.exe and follow the setup instructions.

9) Run umdf.exe and follow the setup instructions.

10) Reboot the computer.

11) Run wmdbexport.exe (it will execute without anything being displayed).

12) Run wmp11.exe and follow the setup instructions.

13) Reboot the computer.

14) Windows Media Player 11 should now be installed and ready to use.

15) Remove your temporary directory when you are sure everything is working.

Can't RDP? How to enable / disable virtual machine firewall for Azure VM

Oh no!  I accidentally blocked the RDP port on an Azure virtual machine which resulted in not being able to log into the VM anymore.  I did ...