Advanced PLINQO Future Queries, Part 2

The immediate uses of PLINQO Future Queries are readily apparent: Do you have multiple queries that need to be executed back to back? Add future to the back of them and save yourself a few database trips.
What might not be quite as easy to spot, are those places where using a more advanced design pattern can really enhance your application’s performance. Here is an example of one of those patters.

Part 2: Pipeline Loader Patter

There are many times when an application needs to process a series of independent actions, each requiring its own set of database objects. If using LINQ to SQL (prior to PLINQO), this would mean that you need to either hard code the loading of all the necessary data in one place, or allow each action to load its own data in succession; thus leaving you with the options of bad abstraction, or lack of optimization; neither of which are very desirable.

Using the PLINQO Future Queries in conjunction with some simple interfaces, you can create a pipeline system that allows your actions to share one single data loading session. As usual, I feel that code narrates this best:

Use Case

[Test]
public void Test()
{
var actions = new List<IPipelineLoader>
{
new CaseAction { CaseId = "A", Title = "First New Title" },
new CaseAction { CaseId = "A", Title = "Second New Title" },
new UserAction { UserId = 1, Title = "Senior Tester" },
new UserAction { UserId = 2, Title = "Junior Tester" }
};

using (var db = new DemoDataContext())
{
actions.ForEach(a => a.Load(db));
db.ExecuteFutureQueries();
actions.ForEach(a => a.Process());
db.SubmitChanges();
}
}

Interface

public interface IPipelineLoader
{
void Load(DemoDataContext db);
void Process();
}

Implementation

public class CaseAction : IPipelineLoader
{
private FutureValue<Case> _futureCase;

public string CaseId { get; set; }
public string Title { get; set; }

public void Load(DemoDataContext db)
{
_futureCase = db.Case.ById(CaseId).FutureFirstOrDefault();
}

public void Process()
{
_futureCase.Value.Title = Title;
}
}

public class UserAction : IPipelineLoader
{
private FutureValue<User> _futureUser;

public int UserId { get; set; }
public string Title { get; set; }

public void Load(DemoDataContext db)
{
_futureUser = db.User.ById(UserId).FutureFirstOrDefault();
}

public void Process()
{
_futureUser.Value.Title = Title;
}
}