I've created a little demo application now that I've had a chance to get some better real-world experience with creating a Microsoft Sync Framework for ADO.NET application.
I feel that the first rule of creating an application that will work in offline mode using Sync is to get your basic application working without sync, talking to a local CE database. It's important to keep in mind all the usual concurrency issues involved with creating a database application such as:
- multiple users updating the same row
- updating something that someone else deleted
- deleting something that someone else updated
- etc...
These issues become even more of a problem when using Sync since the time between the user pressing "Save" and when it actually gets written to the central database can be a long time if they're offline. Also due to this disconnected nature you'll need to handle it at the server, which means you might want to create a "conflict" table to store any client-side changes that are going to be rejected so that user can be notified that their change failed for some reason and given the chance to merge or retry their update.
In this demo app I'll keep it simple, we'll assume that whoever makes the last change to a row wins, since each person should only be updating their own time-sheet.
Our app flow is as follows:
- Pick an employee from a list
- Select a day (date) to add/edit/delete entries for
- Add/edit/delete entries
- Save changes to this day's entries
- Go back to (2) and pick another day or exit (you could also select another employee if you want and start again)
You'll notice that there's no ability to do any updates to the list of Employees, Projects or BillingInfos (list of billing codes), these are considered management tasks and should be done by a separate application (which I might build later if people are interested).
I like to have a "Splash Window", especially since .NET (and WPF even more so) applications can take a while to start, and it'll come in handy later when we'll want to deal with checking the local DB, possibly showing a config window, or even asking for a login.
So, our app is very simple:
- SplashWindow - simple window to let people know the app is starting, will be handy later for other things
- TimeSheetWindow - where everything happens
- LocalDatabase.sdf - SQL CE database with our 4 tables
- CreateLinqToSql.cmd – a batch file to generate the LINQ to SQL classes
- Data\LocalDatabase.cs – generated code for LINQ to SQL
- Data\LocalDataContext.cs – partial class, uses connection string from config
- Data\Employee.cs – partial class, added a FullName property
- Data\TimeEntry.cs – partial class, sets ID to a new GUID when created
You’ll notice the user experience isn’t very satisfying and data validation is quite minimal, but it’s enough for this sample. One possible way to improve it is to use the Xceed DataGrid for WPF (free edition), which also includes a nice DatePicker control.
You can download the application from Time Tracker Demo on Google Code, if you have TortoiseSVN or similar you'll be able to easily download the code and try it out, this version is branch “Stage1”.