Here is an interesting topic. My ideal data access pattern means that there is a single query per controller per request (a request may involve several controllers, though). That is for reading data, obviously, for writing, I will batch the calls if needed. I am making heavy use of the Multi Criteria/Query in order to make this happen.
I have run into a snug with this approach, however. The problem is that some of the services also do data access*. So I may call to the authorization service to supply me with the current user and its customer, and the service will call the DB to find out about this information. I would rather that it would not do that, since that means extra round trips. Now, NHibernate has the idea of a DetachedCriteria, a query that has semi independent life, can be constructed at will and massaged to the right shape anywhere in the code.
Now, I have the following options. Use the normal method:
ICollection<Customer> customers = AuthorizationService.GetAssociatedCustomers();
ICollection<Policy> policies = Repository<Policy>.FindAll(
Where.Policy.Customer.In(customers)
);
PropertyBag["customers"] = customers;
PropertyBag["policies"] = policies;
Use DetachedCriteria as a first level building block:
DetachedCriteria customersCriteria = AuthorizationService.GetAssociatedCustomersQuery();
IList results = session.CreateMultiCriteria()
.Add(customersCriteria)
.Add(DetachedCriteria.For<Policy>()
.Add( Subqueries.PropertyIn("id", CriteriaTransformer.Clone(customersCriteria)
.SetProjection(Projections.Id())
) )
).List();
ICollection<Customer> customers = Collection.ToArray<Customer>(results[0]);
ICollection<Policy> policies = Collection.ToArray<Policy>(results[1]);
PropertyBag["customers"] = customers;
PropertyBag["policies"] = policies;
Remember, I consider Querying a Business Concern, so I like the ability to move the query itself around.
Thoughts?
* By data access, I mean, they call something that eventually resolves in a DB call.