Repository design med LINQ – object-relational mappers

by DotNetNerd 10. May 2009 14:25

Object-Relational Mappers eller bare ORM’s er værktøjer der håndterer det at mappe imellem relationelle data i en database til objekter som vi gerne vil arbejde med dem (og tilbage igen naturligvis). Der findes efter hånden et hav af forskellige ORM eller ORM-lignendene værøtøjer hvor nogen af de mest udbredte er SubSonic, LightSpeed, NHibernate, LINQ to SQL og LINQ to Entities.

Personligt er det de 3 sidstnævnte jeg hovedsageligt har erfaring med, og hvor NHibernate er det jeg primært anvender idag. Der er mange ting at vurdere når man vælger et ORM, men det der normalt afgør ens valg er kompatibilitet med andre teknologier, hvor “tungt” frameworket er og hvor fleksibelt det er. Med fleksibilitet menes her normalt hvordan man kan beskrive sine mapninger og hvilke typer mapninger der er mulige. Det er eksempelvis ikke alle der understøtter mange-til-mange relationer.

Som helt kort guideline vil jeg idag anbefale NHibernate hvis man skal have mest mulig fleksibilitet, LINQ to Entities hvis man vil have best mulig kompatibilitet med .NET teknoligier (især kommende teknologier) og en af de sidst hvis man gerne vil have et mere letvægts ORM der er let at gå til.

Jeg skal muligvis passe på med at kalde LINQ to SQL/Entities for ORM’s, da især Microsoft argumenterer for at de er noget lidt andet. De fleste anser dem dog som ORM’s, og jeg vil også argumentere for at det er hvad produktet er “at it’s core”.

En anden udbredt misforståelse er at LINQ i sig selv er en database teknologi og har noget med et ORM at gøre. Det er imidlertid forkert, da LINQ udelukkende som navnet (Language INtegrated Query) antyder er et sprog til at skrive querys imod en eller anden for for datastore. LINQ providerne til SQL/Entities udgør imidlertid hvad jeg vil kalde ORM’s, da de netop håndterer mapning og persistering af data i databaser.

Der findes en version af LINQ to NHibernate, som efter min mening giver den bedste blanding af et gennemprøvet og fleksibelt modelleringsværktøj i NHibernate, sammen med et lækkert query sprog i LINQ. Til komplekse querys har det imidlertid stadig nogle fejl og mangler, så træerne vokser ikke ligefrem ind i himlen.

En af de ting der bliver talt en del om idag, og som især LINQ to SQL/Entities bliver kritiseret for ikke at give er en Persistence Ignorent domænemodel.

“Persistence ignorance (PI) is a property of "ordinary classes where you focus on the business problem at hand without adding stuff for infrastructure-related reasons.”

Det vil sige om man skal skrive kode i selve modellen der beskriver hvordan objekterne mappes, og om valget af ORM stiller nogen krav til ens øvrige kode.

PI er især et fokusområde for agile udviklere, og det er heldigvis et område Microsoft har fået øjnene op for, således at de har arbejdet på at opnå PI med LINQ to Entities i v2. Lige som afsluttende bemærkning kan jeg nævne at successen med at implementere det nok kommer til at afgøre mit valg af ORM fremover.

disco%20orm1

Tags: ,

Comments (4) -

Niels Brinch
Niels Brinch Denmark
5/28/2009 1:14:52 PM #

Christian, har du så valgt et ORM nu? Anbefaler du LINQ for NHibernate? Rå LINQ? Rå NHibernate?

Kan man i øvrigt degrade til ren SQL med NHibernate, ligesom man kan med LINQ?

DotNetNerd
DotNetNerd
5/28/2009 2:59:06 PM #

Jeg vil sige det er an på hvilken type løsning jeg skal lave - i grove træk om det er noget helt simpelt eller om jeg har brug for de ting NHibernate og Linq 2 Entities tilbyder.

På arbejde vil svaret dog næsten altid være, ja det har jeg brug for. Idag ville jeg så vælge NHibernate og bruge Linq 2 NHibernate + Fluent NHibernate - som også er det jeg bruger på mit nuværende projekt.

Når .NET v4 udkommer tror jeg imidlertid at jeg vil overveje at skifte til Linq 2 Entities. Det virker til de har løst nogle af de mangler det har idag, så det er lige så godt som NHibernate, samtidig med at det er et mere naturligt fit hvis man vil bruge ADO.NET dataservices og ASP.NET Dynamic Data.

Jeg er ikke helt sikker på hvad du mener med "degradere" til ren SQL. Alle ORM's ender med at generere SQL - der er bare et spørgsmål om hvor stort et framework der er bygget henover, og hvilken funktionalitet/fleksibilitet de enkelte tilbyder.

Niels Brinch
Niels Brinch Denmark
6/9/2009 3:18:12 PM #

Selvfølgelig anvender de inderst inde SQL, men det jeg mente var, at hvis man med LINQ har lyst til at skrive sin query i ren SQL i stedet, står det én frit for, og man får stadig alle de andre fordele.

dbContext.ExecuteQuery og .ExecuteCommand tror jeg de hedder.

DotNetNerd
DotNetNerd
6/9/2009 7:17:32 PM #

Man kan på samme måde skrive querys som entity sql, men ikke ren sql. Det vil ikke vil give mening i forhold til at man queryer en entity model, og ikke blot nogle relationelle tabeller. Tror heller aldrig jeg vil savne det...

Who am I?

My name is Christian Holm Diget, and I work as an independent consultant, in Denmark, where I write code, give advice on architecture and help with training. On the side I get to do a bit of speaking and help with miscellaneous community events.

Some of my primary focus areas are code quality, programming languages and using new technologies to provide value.

Microsoft Certified Professional Developer

Microsoft Most Valuable Professional

Month List

bedava tv izle