A scalar immediate execution query is a LINQ query which performs an aggregation (such as Count or Group) or returns only one element (such as First or Single). Because these methods force immediate execution of the query they can't be directly used with asynchronous queries, but using the AsScalarAsync method you can execute scalar immediate execution queries asynchronously.
You've probably noticed something about a query like the following:
C# | int ct = manager.Customers.Count(); |
Or consider another example:
C# | Customer cust = manager.Customers.First(); |
Both these queries are immediate execution queries in LINQ. They differ from the usual deferred execution queries which allow you to build a query in one step and execute the query at a later time. Immediate execution queries execute, well, immediately, and synchronously; you can't separate the creation of the query from the execution.
In an asynchronous environment such as Silverlight, where all queries sent to the EntityServer must be executed asynchronously, immediate execution queries pose a problem. For example, you can't do the following:
C# | // Will not work! var query = manager.Customers.First(); query.ExecuteAsync(); |
Enter the DevForce AsScalarAsync operator and the EntityScalarAsyncExtensions . It's easiest to understand this with an example.
C# | var op = manager.Customers.AsScalarAsync().Count(); op.Completed += (o, e) => { int ct = e.Result; }; |
Like their synchronous counterparts, these methods can also accept a predicate. For example,
C# | var op = manager.Employees.AsScalarAsync().First(e => e.LastName.StartsWith("D")); op.Completed += (o, e) => { Employee emp = e.Result; }; |
You can also write more complex queries, such as the one below using an Include:
C# | var op = manager.Employees.Include("Orders").AsScalarAsync().FirstOrNullEntity(e => e.Id == 1); op.Completed += (o, e) => { Employee emp = e.Result; var orders = emp.Orders; // Will not be pending. }; |
Here's a query built dynamically:
C# | var query = EntityQuery.Create(typeof(Customer)); var pd = PredicateBuilder.Make("CompanyName", FilterOperator.StartsWith, "D"); var op = query.Where(pd).AsScalarAsync().First(); op.Completed += (o, e) => { var cust = e.Result; }; |
The supported immediate execution methods are: All, Any, Average, Contains, Count, First, FirstOrDefault, FirstOrNullEntity, LongCount, Max, Min, Single, SingleOrDefault, SingleOrNullEntity, and Sum. Examples of each are provided in the API documentation .