Future queries
Watch the Futures video on YouTube.
Build up a list of queries for the data you need, and the first time you access any of the results, PLINQO retrieves all the data in one round trip to the database server. Fewer round trips make applications faster.
To use future queries, import the CodeSmith.Data.Linq namespace and append .Future() to your queries:
// build up multiple queries
var q1 = db.User
.ByEmailAddress("one@test.com")
.Future();
var q2 = db.Task
.Where(t => t.Summary == "Test")
.Future();
// this triggers the loading of all the future queries
var users = q1.ToList();
No data is retrieved until q1.ToList() runs. Then PLINQO runs all the future queries automatically, as one batch.
You can also cache the results with FutureCache:
// cache these results for 120 seconds
var q1 = db.User
.ByEmailAddress("one@test.com")
.FutureCache(120);
var q2 = db.Task
.Where(t => t.Summary == "Test")
.FutureCache(120);
// this triggers the loading of all the future queries
var users = q1.ToList();
Creating future queries
You create future queries with the Future(), FutureFirstOrDefault() and FutureCount() extension methods.
var db = new TrackerDataContext();
// build up queries
var q1 = db.User
.ByEmailAddress("one@test.com")
.Future();
var q2 = db.Task
.Where(t => t.Summary == "Test")
.Future();
// this triggers the loading of all the future queries
var users = q1.ToList();
This example builds up two queries. As soon as one of them is enumerated, both are loaded in one batch.
A common scenario is paging a list of tasks. To set up the paging control, the UI also needs the total count. With future queries, you get both in one database call:
var db = new TrackerDataContext();
// base query
var q = db.Task.ByPriority(Priority.Normal);
// get total count
var q1 = q.FutureCount();
// get page
var q2 = q.Skip(pageIndex).Take(pageSize).Future();
// triggers sql execute as a batch
int total = q1.Value;
var tasks = q2.ToList();
Caching future queries
You can cache future queries with the same settings as the FromCache extension method. Each query is cached separately.
var db = new TrackerDataContext();
// cache for 120 seconds
CacheSettings cache = new CacheSettings(120);
// build up queries
var q1 = db.User
.ByEmailAddress("one@test.com")
.FutureCache(cache);
var q2 = db.Task
.Where(t => t.Summary == "Test")
.FutureCache(cache);
// this triggers the loading of all the future queries
var users = q1.ToList();
How future queries work
- Each future query creates an
IFutureQueryobject that keeps theIQueryable. - The
IFutureQueryobject is stored in theIFutureContext.FutureQuerieslist of theDataContextthat created the query. TheDataContextmust implementIFutureContext. - When one of the
IFutureQueryobjects is enumerated, it calls back toIFutureContext.ExecuteFutureQueries()through theLoadActiondelegate. ExecuteFutureQueriesbuilds a batch query from all the storedIFutureQueryobjects.- All the
IFutureQueryobjects are updated with the results.
Note
Future queries don't support anonymous types.