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)
) ) ).List(); ICollection<Customer> customers = Collection.ToArray<Customer>(results); ICollection<Policy> policies = Collection.ToArray<Policy>(results); PropertyBag["customers"] = customers; PropertyBag["policies"] = policies;
Remember, I consider Querying a Business Concern, so I like the ability to move the query itself around.
* By data access, I mean, they call something that eventually resolves in a DB call.