Entity Framework is een populair ORM framework binnen .NET. In dit artikel wil ik een paar dingen benoemen die je mogelijk al wel kent, maar die je in de praktijk kunnen helpen bij het gebruik van Entity Framework.

Houd je IQueryables alsjeblieft in je datalaag of repositories

Toegegeven, deze fout heb ik zelf gemaakt toen ik lang geleden mijn eerste project met Entity Framework maakte. Ik dacht nog… dat is tof, ik geef vanuit mijn datalaag een IQueryable terug en die kan ik dan desgewenst op allerlei manieren uitbreiden.

Tot zover de theorie. Dan nu de praktijk. Je hebt geen idee meer hoe queries in je applicatie tot stand komen en alles raakt aan alles verbonden waardoor je geen idee meer hebt wat er in de applicatie gebeurt als je één van de basis queries uit je datalaag aanpast. Bovendien wordt de query asynchroon uitgevoerd zodat de plek waar de fout optreedt in je code, en de plek waar deze in de foutmelding genoemd wordt geen logische relatie meer hebben. Met andere woorden. Houdt die iqueryables in de datalaag. Persoonlijk blijf ik overigens dus voorstander om mijn Entity Framework context niet rechtstreeks te gebruiken, maar altijd via Repositories (al dan niet in een aparte library).

DbSets zijn niet nodig in de context

Stel je hebt een aantal simpele objecten:

1-simpele objecten

Je zou deze als DbSet kunnen toevoegen in de context:

2-dbset

Ik maak echter liever gebruik van de modelBuilder zodat de entiteiten niet rechtstreeks via de context zichtbaar worden (ik wil ze immers via de repository gebruiken). Meestal maak ik de context ook internal zodat deze ook niet gebruikt kan worden buiten de repositories.

3-application-dbcontext

De modelbuilder is sowieso meestal nodig omdat je details wilt instellen m.b.t. relaties, veldnamen en overige details die je niet in het model kwijt wil.

Beetje iffy, maar het updaten van child items

Persoonlijk zou ik liever mijn code opbouwen zodat het logischerwijs doet wat ik uitvoer, maar het is goed om te weten dat Entity Framework een behoorlijk slimme manier heeft om je wijzigingen te beoordelen. Stel bijvoorbeeld dat je de volgende code uitvoert:

4-voorbeeldcode

Je zou verwachten dat in dit geval alle huidige adressen worden verwijderd en er nieuwe worden toegevoegd. Echter omdat het eerste adres een id heeft dat ook in de database voorkomt, snapt EF dat het de volgende queries moet bouwen:

5-database query

Dit betekend ook dat we moeten opletten in de acties die we doen omdat EF dus in sommige gevallen niet uitvoert wat je in de code schrijft.

Gebruik van Find versus First

Het gebruik van First resulteert in een select query die de eerste gevonden waarde teruggeeft. In de praktijk zal die query altijd uitgevoerd worden, ook als je meerdere keren hetzelfde object uit de context nodig heb (binnen één scope). Door gebruik te maken van Find, zoek je objecten op op basis van hun primary key. Het voordeel is dat de tweede keer dat je hetzelfde object opvraagt, de context niet opnieuw naar de database gaat:

6-afbeelding-find

Gebruik maken van transacties

In principe is de SaveChanges opdracht van EF al zodanig gebouwd dat je een hele set aan wijzigingen in één keer opslaat. Soms ontkom je er alleen niet aan dat je verschillende methodes met elk hun eigen SaveChanges combineert. In dat geval kun je een transactionscope gebruiken om wijzigingen op te slaan of te annuleren.

7-user-service

Chaining linq queries

Je ziet wel eens queries waarbij de Where clausule zo complex is dat je hem tig keer moet lezen om er wat van te kunnen maken. Het is goed om te weten dat je queries eindeloos kunt uitbreiden. EF maakt er zelf wel een goede query voor de database van.

8-linq-queries

Liever dus meerdere Where clausules onder elkaar dan één niet te lezen constructie. Misschien denk je dat de verschillende clausules apart uitgevoerd worden, en dus trager zijn. Dat is niet het geval, want Entity Framework maakt er altijd één query van die in één keer uitgevoerd wordt.
Hopelijk ben je nog iets tegengekomen wat je nog niet wist. Happy coding, en tot de volgende keer.

Menno