In the last two parts of this session I have shown how to develop Silverlight application that shows information from a database in occasion connected environment. In this last part I will show you how to manage updates (including inserting and deleting records) and synchronizing them back into the database.
The first step is to make sure we are working with the relevant DomainContext object and to apply all the updates to the offline/online DomainContext, depending on the application’s status. To accomplish this I have created a factory method that checks the application’s status and returns the relevant DomainContext. This method should be used whenever we need a DomainContext object in Silverlight projects.
public static NorthwindDomainContext GenerateNewNorthwindDomainContext() { NorthwindDomainContext northwindDomainContext; if (OfflineHelper.IsApplicationOnline) { northwindDomainContext = new NorthwindDomainContext(); } else { northwindDomainContext = (NorthwindDomainContext)DomainContextExtension. GetOfflineDomainContext(typeof(NorthwindDomainContext)); } return northwindDomainContext; }
The second step is submitting the changes. To accomplish that, we will need to check the application status; if it is online we should use the out of the box SubmitChanges method and if it is offline, we just call the OCSaveAsOfflineDomainContext that we implemented in the previous parts. Since the Entity object is tracing all the changes, we do not need to do anything except serialize the updated DomainContext to the offline storage. To simplify the operation I created this extension method:
public static Task OCSubmitChangesAsync(this DomainContext source) { if (OfflineHelper.IsApplicationOnline) { return source.SubmitChangesAsync(); } else { return TaskEx.Run(() => { source.OCSaveAsOfflineDomainContext(); }); } }
The third and last step is synchronizing with the database when the application becomes online. All we need is to call the SubmitChanges on the offline DomainContext. Although the MSDN sample that enables serializing RIA DomainContext objects fit the job, it still required fixing some bugs to make it work properly (I attached the final code at the button of the post). Again, I warp it up with an extension method:
public static Task OCSyncWithOnlineServiceAsync(this DomainContext source) { Task result = null; if (OfflineHelper.IsApplicationOnline) { DomainContext offlineDomainContext = GetOfflineDomainContext(source.GetType()); try { result = offlineDomainContext.SubmitChangesAsync(); } catch (Exception ex) { HandleSyncErrors(ex); } } return result; }
An example of using the above methods for doing offline updating, would look something like this:
NorthwindDomainContext domainContext = DomainContextFactory.GenerateNewNorthwindDomainContext(); await this.domainContext.LoadAsync(this.domainContext.GetCustomersQuery()); this.domainContext.OCSaveAsOfflineDomainContext(); OfflineHelper.IsApplicationOnline = false; domainContext = DomainContextFactory.GenerateNewNorthwindDomainContext(); // Do some update on domainContext objects... OfflineHelper.IsApplicationOnline = true; await this.domainContext.OCSyncWithOnlineServiceAsync();
In addition, I have also attached a simple application that demonstrates the use of this framework. Notice that you can take the application offline, make changes, close and open the application and the changes will still be there. The application is also able to run out of the browser so you will be able to run this application even after the web server and the SQL server are unavailable.
Summary: To convert your application to support offline scenarios you will need to follow these steps:
- Download and install the Microsoft Visual Studio Asynchronous Framework.
- Add reference to the SilverlightOccasionallyConnected DLL.(attached to this post)
- Create a factory method as demonstrated, to create DomainContext and use only this method throughout the Silverlight projects.
- Use the OCLoadAsync and OCSubmitChangesAsync to query and submit your changes respectively.
- Make sure that the filter and order-by logic are located in the Silverlight projects and not on the Server-side project.
- Add to your application this functionalities :
- An offline/online indication
- An option to generate offline copy of the database using the OCSaveAsOfflineDomainContext function. Load all the data that your application will need access to in offline mode before calling this method.
- An option to synchronize using the OCSyncWithOnlineServiceAsync function.