DevForce provides the ability to query asynchronously for two reasons:
1) The Silverlight CLR (common language runtime) environment does not permit synchronous web service calls.
2) Even in those environments where synchronous API's are supported, there are many use cases where performance can be improved via the use of an asynchonous query.
While an overview of asynchonous programming in DevForce discusses the specific asynchronous API's provided in the context of querying. Please review the overview document for context if necessary.
The return value from any call to either a EntityQueryExtensions.ExecuteAsync or a EntityManager.ExecuteQueryAsync is an instance of EntityQueryOperation<T>. This operation result can be either be accessed directly within the method's callback logic or via the operation's Completed event. In the case of the Completed event; the event delegate gets passed a EntityQueriedEventArgs<T> parameter.
Regardless of whether you are working with an EntityQueryOperation<T> or an EntityQueriedEventArgs<T>, the following read only properties are provided in addition to those inherited from the BaseOperation or AsyncEventArgs base classes. Please see Program asynchronously for more detail on the standard DevForce asynchronous model and the properties available there. The following discussion is only about those additional properties that are available during an asynchonous query.
Property | Property Type | Description |
---|---|---|
EntityQuery | IEntityQuery<T> | The requested query |
Results | IEnumerable<T> | The results of the query. |
ChangedEntities | IList<Object> | The list of every entity that was either added or modified in the EntityManager's cache as a result of this query. The ChangedEntities list may differ from the Results property since the Results will include only those entities directly queried, and not entities fetched due to query inversion or use of an "Include". |
WasFetched | bool | Whether the operation actually required a trip to the database. Many queries can be completed without having to go to the database. |
ResolvedFetchStrategy | FetchStrategy | The FetchStrategy actually used to process the query. This is really only useful when an 'optimized' FetchStrategy was stipulated when executing the query. What is returned here is the query strategy that 'optimized' determined was most appropriate. |
DevForce provides two primary ways to perform asynchronous queries. The first is to use any of the ExecuteAsync() extension methods or EntityManager.ExecuteQueryAsync() method overloads. For example:
C# | var query = _em1.Customers .Where(c => c.ContactTitle == "Sales Representative") .OrderBy(c => c.CompanyName); // Using IEntityQuery.ExecuteAsync with lambda syntax: query.ExecuteAsync( op => { IEnumerable<Customer> customers = op.Results; }); // Using EntityManager.ExecuteQueryAsync with lambda syntax: _em1.ExecuteQueryAsync(query, op => { IEnumerable<Customer> customers = op.Results; }); // Using IEntityQuery.ExecuteAsync with Completed event syntax: var op = query.ExecuteAsync(); op.Completed += (sender, eventArgs) => { IEnumerable<Customer> customers = eventArgs.Results; }; // Using EntityManager.ExecuteQueryAsync with Completed event syntax: var op = _em1.ExecuteQueryAsync(query); op.Completed += (sender, eventArgs) => { IEnumerable<Customer> customers = eventArgs.Results; }; |
VB | Dim query = _em1.Customers.Where(Function(c) c.ContactTitle = "Sales Representative").OrderBy(Function(c) c.Compa ' Using IEntityQuery.ExecuteAsync with lambda syntax: query.ExecuteAsync(Sub(op) Dim customers As IEnumerable(Of Customer) = op.Results) ' Using EntityManager.ExecuteQueryAsync with lambda syntax: _em1.ExecuteQueryAsync(query, Sub(op) Dim customers As IEnumerable(Of Customer) = op.Results) ' Using IEntityQuery.ExecuteAsync with Completed event syntax: Dim op = query.ExecuteAsync() AddHandler op.Completed, Sub(sender, eventArgs) Dim customers As IEnumerable(Of Customer) = eventArgs.Results ' Using EntityManager.ExecuteQueryAsync with Completed event syntax: Dim op = _em1.ExecuteQueryAsync(query) AddHandler op.Completed, Sub(sender, eventArgs) Dim customers As IEnumerable(Of Customer) = eventArgs.Results |
For what are termed "scalar queries", i.e. queries that return an immediate single result, the mechanism is slightly different and uses the IEntityQuery.AsScalarAsync() extension method. An example is shown below:
C# | var query = _em1.Customers .Where(c => c.ContactTitle == "Sales Representative") .OrderBy(c => c.CompanyName); // Using lambda syntax query.AsScalarAsync().FirstOrNullEntity( op => { Customer cust = op.Result; }); // Using Completed event syntax var op = query.AsScalarAsync().FirstOrNullEntity(); op.Completed += (sender, eventArgs) => { Customer cust = eventArgs.Result; }; |
VB | Dim query = _em1.Customers.Where(Function(c) c.ContactTitle = _ "Sales Representative").OrderBy(Function(c) c.CompanyName) ' Using lambda syntax query.AsScalarAsync().FirstOrNullEntity(Sub(op) Dim cust As Customer = op.Result) ' Using Completed event syntax Dim op = query.AsScalarAsync().FirstOrNullEntity() AddHandler op.Completed, Sub(sender, eventArgs) Dim cust As Customer = eventArgs.Result |