SQL Compact Code Generator

More than a year ago, I published a project on CodePlex called SQL Compact Code Generator. Unfortunately, I never managed to find the time to do some work on it and the project was set on a very long hold. A year after I suddenly really needed such a tool and decided that I should put in some hours on the project.

I’m currently working on a large enterprise project where changes to the database schema is done rather frequently, to avoid the pain of updating my data layer after every change I decided to use my code generator.

Here’s some details I pulled directly off the CodePlex Github page.

Project Description

Contains a stand alone GUI application and a Visual Studio Custom Tool for automatically generating a .NET data access layer code for objects in a SQL Server Compact Edition database.

Features:

  • Visual Studio 2008 and 2010 Custom Tool Support
  • Creates entity classes for each table in the database
  • Generates data access code that implements the Repository Pattern
  • Generates methods for Create, Read, Update and Delete operations
  • Generates SelectBy and DeleteBy methods for every column in every table
  • Generates a Purge method for every table to delete all records
  • Generates Count() method for retrieving the number of records in each table
  • Generates CreateDatabase() method for re-creating the database
  • Generates xml-doc code comments for entities and data access methods
  • Generates Entity Unit Tests
  • Generates Data Access Unit Tests
  • Generates .NET Compact and Full Framework compatible code
  • Support for SQL Compact Edition version 4.0
  • Multiple test framework code generation (MSTest, NUnit, xUnit)
  • Transaction support per DataRepository instance (Begin, Commit, Rollback)
  • Code generation options to enable/disable unit test code generation
  • Windows Phone 7 “Mango” support for generating a LINQ to SQL DataContext

Data Access Custom Tools:

  • SQLCECodeGenerator - Generates entity and data access components using a single file.
  • SQLCEMangoCodeGenerator - Generates Windows Phone 7 “Mango” SQLCE entity and data access components using a single file
  • SQLCECodeGeneratorV2 - Generates entity and data access components using several files. One file per class or interface
  • SQLCEMangoCodeGeneratorV2 - Generates Windows Phone 7 “Mango” SQLCE entity and data access components using several files. One file per class or interface

Data Access Unit Test Custom Tools:

  • SQLCEMSTestCodeGenerator - Generates entity and data access unit test code that targets MSTest using a single file
  • SQLCENUnitCodeGenerator - Generates entity and data access unit test code that targets NUnit using a single file
  • SQLCEXUnitCodeGenerator - Generates entity and data access unit test code that targets xUnit.net using a single file
  • SQLCEMSTestCodeGeneratorV2 - Generates entity and data access unit test code that targets MSTest using several files. One file per class or interface
  • SQLCENUnitCodeGeneratorV2 - Generates entity and data access unit test code that targets NUnit using several files. One file per class or interface
  • SQLCEXUnitCodeGeneratorV2 - Generates entity and data access unit test code that targets xUnit.net using several files. One file per class or interface

Screenshots



How to display a Notification Bubble in Windows Mobile using .NETCF

Yesterday, I found myself using an old piece of code that I wrote ages ago. It’s something I’ve used every now and then for past few years. Since I myself find it useful, I might as well share it. All the code does is display a Notification Bubble in Windows Mobile. To do this you use the Notification class in the Microsoft.WindowsCE.Forms namespace. Even though the Notification class is very straight forward and easy to use, I created a helper class so that I only need to write one line of code for displaying a notification bubble:

NotificationBubble.Show(2, "Caption", "Text");  

Implementation:

/// <summary>
/// Used for displaying a notification bubble
/// </summary>
public static class NotificationBubble
{
    /// <summary>
    /// Displays a notification bubble
    /// </summary>
    /// <param name="duration">Duration in which the notification bubble is shown (in seconds)</param>
    /// <param name="caption">Caption</param>
    /// <param name="text">Body</param>
    public static void Show(int duration, string caption, string text)
    {
        var bubble = new Notification
        {
            InitialDuration = duration,
            Caption = caption,
            Text = text
        };
 
        bubble.BalloonChanged += OnBalloonChanged;
        bubble.Visible = true;
    }
 
    private static void OnBalloonChanged(object sender, BalloonChangedEventArgs e)
    {
        if (!e.Visible)
            ((Notification)sender).Dispose();
    }
}

Hope you found this helpful.



Working around Pivot SelectedIndex limitations in Windows Phone 7

I’ve been working on an application with 2 pages, a main page and a content page. The content page contains a Pivot control with a few pivot items. The main page does nothing but navigate to the content page and suggest which pivot item to display. The only reason the main page exists is to display the information in the pivot item headers in a more graphical and elegant way.

For some reason I can’t set the displayed pivot index to be the third item. I wanted to do this on the OnNavigatedTo event of the content page but whenever I attempt doing so an exception is thrown. Every other pivot item works fine, which I think is really weird.

To load the content page, I navigate to the page by passing some information of the pivot index I wish to be displayed. Something like this:

NavigationService.Navigate(new Uri("/ContentPage.xaml?index=" + index, UriKind.Relative));

If the value of index in the code above is set to 2 then I get an exception, any other valid value works fine. A value out of range (less than 0 or greater than 5) throws an out of range exception which is the behavior anyone would expect.

Here’s the XAML definition of the content page

<phone:PhoneApplicationPage
    x:Class="WindowsPhonePivotApplication.ContentPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait"  Orientation="Portrait"
    shell:SystemTray.IsVisible="True">
 
  <Grid x:Name="LayoutRoot" Background="Transparent">
    <controls:Pivot Name="pivot" Title="CONTENT PAGE">
      <controls:PivotItem Header="first" />
      <controls:PivotItem Header="second" />
      <controls:PivotItem Header="third" />
      <controls:PivotItem Header="fourth" />
      <controls:PivotItem Header="fifth" />
      <controls:PivotItem Header="sixth" />
    </controls:Pivot>
  </Grid> 
</phone:PhoneApplicationPage>

To work around this limitation, you can handle the Loaded event of the page and update the pivot selected index from there. Here’s an example how to do it:

public partial class ContentPage : PhoneApplicationPage
{
    private int pivotIndex;
 
    public ContentPage()
    {
        InitializeComponent();
 
        Loaded += delegate { pivot.SelectedIndex = pivotIndex; };
    }
 
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        string value;
        if (NavigationContext.QueryString.TryGetValue("index", out value))
        {
            pivotIndex = 0;
            int.TryParse(value, out pivotIndex);
        }
    }
}

I’m not sure if this limitation is by design or it’s a bug in the control. Either way I managed to get it to work the way I wanted it to. Hopefully I’m not the only one who ran across this and that you found this information useful.