Hiding NHibernate with Linq
Been using NHibernate a lot recently, and just love having POCO data objects. This means that i can just hand out objects and manipulate them and then save them back to the DB without ever exposing my persistence model. For this purpose, I'd been using Data Access Objects to give me access to the objects. But like stored procedures, after a while you DAOs have this mess of Find methods on them that either have many overloads or, even worse, optionally nullable parameters. Never mind the acrobatics you jump through once you want to provide methods that query entities, based on some other entity, that's abstracted by its on DAO.
The option was to expose the NHibernate query api (talking ICriteria here, never touched HQL because the reason i went NHibernate in the first place is because i didn't want queries in strings), but that didn't taste right, so i added more methods on my DAO instead, hiding the criteria queries.
Once i started playing with the experimental Linq support, i didn't change my abstraction, just started using Linq instead of criteria inside the DAO. But last week, I finally broke down and just exposed session.Linq<T>();
as an IQueryable<T>
on my DAO. For example my Account DAO, AccountService
now simply looks like this:
public interface IAccountService
{
Account CreateAccount(JObject json);
Account GetAccount(int accountId);
IQueryable<Account> Accounts { get; }
void Save(Account account);
}
NHibernate is completely invisible, I have full query capabilities and even mocking has become easier, just returning a List<T>.AsQueryable()
from my mock DAO. I was able to remove all my Find methods. I did leave the by Id accessor GetAccount
in there, just because it's the predominant use case, and i didn't want to litter code with identical Linq queries.
I have to say, i like this approach a lot.