Migrations
Genereert update scripts die op volgorde uitgevoerd moeten worden
Benodigdheden
- Install package
Microsoft.EntityFrameworkCore.Design
- In csproj
<ItemGroup><DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" /></ItemGroup>
Command line
- Aanmaken van een nieuwe migratie versie:
dotnet ef migrations add <naam>
- Maakt in een Migrations mapje deze migratie aan
- Migraties in volgorde op een (niet bestaande) database uitvoeren
dotnet ef database update <naam (optional)>
- Pakt default de nieuwste migration
- Dus alle voorgaande migraties worden uitgevoerd om tot deze migratie te komen
- Maakt tabel __EFMigrationHistory aan in de database
- Houdt bij welke migratie er het laatst is uitgevoerd
- Sql script genereren op basis van migratie
ef migrations script InitialMigration HouseNumberAdded -o HouseNumberUpdateScript.sql
- In dockerfile osql command voor initiele data
- osql is een command line tool om sql scripts uit te voeren
- Kan dus gebruikt worden om via de dockerfile initiele data in te voeren
CSharp
De database kan bij het opstarten van de applicatie naar de juiste migratie gezet worden door in startup.cs context.Database.Migrate(); in plaats van EnsureCreated(); te gebruiken
Migration files (in Migrations mapje)
- Bevatten verschillende stukjes code voor het aanpassen, toevoegen, verwijderen, etc. van kolommen of tables
- Eventueel de
.Sql(..) methode gebruiken om zelf SQL code uit te voeren
- Niet de beste optie, maar soms wel de enige optie
Concurrency
Pessimistic
- Locks leggen op tables/rows wanneer je iets gaat updaten
- Tip: Zie de samenvatting van alexander petrov
- Geeft meer info over pessimistic locking en indexes
Optimistic
- GEEN locks leggen op tables/rows
- Wanneer de gebruiker klaar is met wijzigen, gaat er een update naar de datbase.
- Tijdens het updaten controleren of de rowversion gewijzigd is
- Dit betekent dat de data in de tussentijd gewijzigd is
- Als de data gewijzigd is in de tussentijd, volgt er een DbUpdateConcurrencyException
In Entity Framework
Een van de volgende:
[ConcurrencyCheck] boven de property zetten
- Werkt niet als de context steeds opnieuw aangemaakt wordt
- Er wordt namelijk geen oude data gecached, dus kan niet meer gecontroleerd worden als die niet in leven gehouden wordt
- In leven houden is geen goede optie, omdat dit memory wegzuigt (memory leak)
- Bij het updaten van een voorraad
- Geef het aantal mee waarmee de voorraad verminderd wordt
- Bij het updaten de huidige voorraad nogmaals ophalen
- Vervolgens de voorraad verminderen en opslaan
- Rowversion meenemen
[Timestamp] public byte[] RowVersion { get; set; }
- Let op: Timestamp geeft niet de daarwerkelijke ‘timestamp’ van het updaten weer. Enkel een versienummer
- Hoe?
- Oude rowversion onthouden (of meegeven aan ViewModel. Kan toch niet aangepast worden)
- Kan vervolgens als ‘<input type=hidden … >’ in de frontend staan
- Velden updaten in frontend
- Op ‘opslaan’ klikken
- In backend de _context.Update(newItem) aanroepen
- Deze ‘newItem’ heeft de oude rowversion en de nieuwe waardes
- Entity Framework Core checkt zelf of de rowversion aangepast is in de tussentijd
- Als ze gelijk zijn, is er in de tussentijd niets ge-update
- Als ze NIET gelijk zijn, is er iets ge-update en moet er een melding getoond worden aan de gebruiker
UI testing
Hoeveel?
Dure testen, dus niet teveel van schrijven
Hoe?
Selenium
Unit testen die selenium code gebruiken om een Chrome browser aan te sturen
Voorbeeld test
IWebDriver browser = new ChromeDriver(/*pad naar chromedriver.exe*/);
browser.Url = "http://localhost:xxxxx/yyyyy";
browser.Close();
var titel = browser.FindElement(By.CssSelector("h1")).Text;
Assert.AreEqual("Magazijnbeheer", titel);
Let op: Als in de ‘new ChromeDriver(..)’ geen argument opgegeven wordt, ontstaat er een error dat chromedriver.exe ontbreekt. Dan chromedriver.exe downloaden van getoonde link
Pages
Pages kunnen gemaakt worden om het navigeren naar een pagina te abstraheren.
internal class MagazijnPage : IDisposable
{
private IWebDriver _browser;
public MagazijnPage()
{
_browser = new ChromeDriver(..);
_browser.Url = ...;
}
public string GetTitel()
{
return browser.Findelement(...);
}
// Etc, etc...
}
Note
Zie Dag29.EFenUITestDemo (van Marco) voor meer voorbeelden
Protractor
Komt in volgend blok
Wat?
End-to-end testen. Deze kijken of de hele keten van UI tot database werkt
Tests
Test soorten
- End-to-end: Van het bovenste tot het onderste deel (Vaak UI tot Database)
- Integratie: Grotere delen
- Unit test: 1 stukje code zonder dependencies
Test piramide

Beschrijft de grootte van de test in verhouding met de hoeveelheid
- Hoe hoger in de piramide, hoe groter
- Hoe breder het vakje, hoe meer er van zijn
Overig
- Entity Framework Core: Alle properties van een model in 1 keer updaten
_context.Entry(oldItem).CurrentValues.SetValues(newitem)