Miksi piilottaa ORM?

Yhä useammin tietokantoja käsitellään ORMien kautta. Yhä vahvemmin olen myös alkanut ajatella, että ORMin piilottaminen jonkin lisäkerroksen taakse on huono idea. Kokosin neljä tapaa hakea dataa sekä niiden hyvät ja huonot puolet. Oletuksena on, että kaikissa vaihtoehdoissa käytetään kuitenkin ORMia joko suoraan tai piilossa.

Metodi per kysely

Hyvin yksinkertainen malli. Jokaiselle erilaiselle kyselylle on oma metodi.

public interface IProductDA
{
  IEnumerable<Product> GetProductsByName(string name);
  IEnumerable<Product> GetProductsByCategory(Guid categoryId);
}

Plussat

Miinukset

Specification tai vastaava pattern

Kyselyt hoidetaan yhdellä tai muutamalla metodille, jotka ottavat vastaan "speksit" (ehdot, eager load, järjestäminen jne.)

public interface IProductDA
{
  IEnumerable<Product> Get(IEnumerable<Filter<Product>> filters, 
                           IEnumerable<Include<Product>> includes, 
                           IEnumerable<Order<Product>> orderings);
}

Plussat

Miinukset

IQueryable

Simppeli wrapper, jolla dataa haetaan IQueryablen kautta.

public interface IDataAccess<T> where T : Entity
{
  void Create(T item);
  void Get(Guid id);
  void Update(T item);
  void Delete(T item);
  IQueryable<T> All();
}
public interface IProductDA : IDataAccess<Product>
{
}

Plussat

Miinukset

ORMin käyttäminen suoraan

Plussat

Miinukset

Yksikkötestaus

Eräs peruste ORMin piilottamiselle on ollut yksikkötestauksen mahdollistaminen. Kuitenkin ainakin NHibernaten ISessionFactory ja ISession ovat helppoja mockattavia, samoin Entity Frameworkin DbContext.

Yhteenveto

Vaikka jokaisella vaihtoehdolla on puolensa, normitapauksissa suosisin niitä alhaalta ylöspäin. ORMin piilottaminen vaatii paljon ylimääräistä koodia, joka ei kuitenkaan tuo lisäarvoa. ORMin vaihto ei kuitenkaan tule tapahtumaan, joten siihenkin varautuminen on turhaa työtä, etenkin kun samalla menetetään kunkin ORMin erityisominaisuudet.