Click here to Skip to main content
Click here to Skip to main content

Client Side Domain Context Load Manager

, 21 Apr 2012
Rate this:
Please Sign up or sign in to vote.
Entity Query Load Manager for Entity Framework Domain Contexts.

Introduction

While in the process of working through multiple solutions requiring numerous queries from different, inter-connecting, Domain Contexts, I required a mechanism of knowing when all the queries had completed.

This is mainly because there was no way of doing an include on the servers, because the data was located in physically different databases, and references were added on the client. This made it even more important as Navigation properties were used for binding on the user controls, and as such had to be locked until such time as the data was available.

MultiSyncQueryLoader

MultiSyncQueryLoader is the wrapping class that is responsible for the notification that all the queries were successfully completed. It has been written in a manner that will allow the same mechanism as you would use for a normal query to a Domain Context, but using the AddQuery method instead.

Just so that I give credit where it is due, my colleague Robin Marshall added in the default context and LoadBehaviour properties to allow simplified queries from the Domain Context.

There are two ways of ultimately querying the data using the loader: asynchronous and synchronous (or at least asynchronous but in sequential order).

The RunSync method was designed for the scenario where a callback of one query required that data be loaded by a query, before that callback was actually run.

The RunAsync method will be more typically used by the day-to-day queries that will be run in a Silverlight / Entity Framework environment. This is designed to fire all the queries simultaneously to the relevant services, and await the responses.

Each of the queries will notify via the Completed event when all the queries have finished loading.

DomainContextQuery<T>

The DomainContextQuery<T> generic is where all the magic happens. Its job is to run the EntityQuery against the associated DomainContext and notify the initiator that it has completed.

The Run(Action) method is responsible for running the synchronous calls, as we do not need to pass in a userstate variable for the listening invoker to know what DomainContextQuery was actually being run.

The Run(Action<object>) method, however, is required for the asynchronous calls. This is so that we can extend the method to use the DomainContextQuery that invoked it, should it be required.

Each method will mark the DomainContextQuery as Complete so that it is quick for the MultiSyncQueryLoader to check if there are any outstanding queries, and if not, fire the Completed event.

Using the Code

To explain the use of the code, I will use an excerpt from the attached demo solution:

MultiSyncQueryLoader loader = new MultiSyncQueryLoader(context, LoadBehavior.MergeIntoCurrent);
loader.AddQuery(context.GetCustomersQuery(), (callback) => CustomersLoaded = true);
loader.AddQuery(context.GetCategoriesQuery(), (callback) => CategoriesLoaded = true);
loader.AddQuery(context.GetCustomerDemographicsQuery(), (callback) => CustomerDemographicsLoaded = true);
loader.Completed += () => CompleteLoaded = true;

// Run the queries in any order
loader.RunAsync();

// Run the queries in the defined order above
// loader.RunSync();

To utilise the code, just create an instance of the query loader (use a default domain context and load behaviour if required). Add each query using the method. The AddQuery method has been designed in a way that will not interfere with the original code.

For example, before the query loader, a load from a Domain Context could have appeared as follows:

context.Load(context.GetCustomersQuery(), LoadBehavior.MergeIntoCurrent, callback => { }, null) 

Whereas now with the AddQuery method (and no default context specified):

loader.AddQuery(context,context.GetCustomersQuery(), LoadBehavior.MergeIntoCurrent, callback => { } , null);

Continued Development

Any future development on this project will be maintained on Github. I will always attempt to place an up-to-date version on the article, but its always best to check.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Kelvin Armstrong

United Kingdom United Kingdom
No Biography provided

Comments and Discussions

 
QuestionZip file not open PinmemberMember 317163221-Apr-12 14:56 
AnswerRe: Zip file not open PinmemberKelvin Armstrong21-Apr-12 21:36 
GeneralRe: Zip file not open PinmemberMember 317163222-Apr-12 20:17 
GeneralMy vote of 5 PinmemberAbinash Bishoyi8-Mar-12 22:18 
GeneralRe: My vote of 5 PinmemberKelvin Armstrong9-Mar-12 7:59 
QuestionMessage Automatically Removed Pingroupghjtyktyk15-Feb-12 15:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140821.2 | Last Updated 21 Apr 2012
Article Copyright 2012 by Kelvin Armstrong
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid