Power Platform: App Maker Challenge, deel 25

Ingediend door Dirk Hornstra op 07-jun-2022 15:16

Het vijfentwintigste deel, verwachte tijd: drie kwartier.
Dit deel gaat over het verminderen van complexiteit in je data model met relaties in Dataverse tabellen.

Als je een datamodel maakt in Dataverse, dan worden tabellen gebruikt om objecten en concepten weer te geven. Zoals in het echt zaken aan elkaar gekoppeld zijn, zo kun je dat ook met relaties in dit model aangeven.

Als je een canvas app maakt en de gebruiker een goede ervaring wilt geven, dan zorg je dat onnodige complexe structuren voor de gebruikt verborgen blijven of overzichtelijk getoond worden. Om dat te realiseren gebruik je formules en je data om dat efficient te doen.

We beginnen met een scenario: de gedeelde werkplekken. Medewerkers van een bedrijf werken thuis, maar soms ook op de zaak. Het was een kwestie van: wie het eerst komt, wie het eerst maalt. Maar dat werkte niet. Dus nu moet er een systeem komen waarin je een werkplek kunt reserveren.

Het datamodel wat hiervoor opgezet wordt is:

  •  locatie: hierin staan de losse gebouwen, bevat adres en telefoonnummer, 1 primair contactpersoon.
  • desk: een werkplek op een bepaalde locatie. Kan dus gereserveerd worden.
  • desk feature: de ene werkplek, die zit in een "stille ruimte". Of is een tafel die ook in hoogte verstelbaar is en als sta-plek gebruikt kan worden. Een werkplek kan meerdere features hebben.
  • user: de werknemer die een plek wil reserveren of de primaire contactpersoon.
  • reservation: een reservering. User X heeft desk A tijdens tijdslot [tijd van - tijd tot].


De relaties. Je kunt een 1-N relatie hebben. Een record heeft dan 0 tot N aantal gekoppelde records.
Er wordt nog verwezen naar een Multi-table lookup column type om dat te realiseren: link. Met IsType en AsType kun je Microsoft Power Fx functies gebruiken om de parent-tabel te bepalen en data te gebruiken.

De medewerkers hebben deze relaties bepaald:

  • Location - Desk, elke desk staat op 1 locatie.
  • User - Location, elke locatie heeft 1 primair contact.
  • User - Reservation, koppeling van: deze reservering hoort bij deze persoon.
  • Desk - Reservation, koppeling van: deze reservering is voor deze desk.


Je kunt ook "gedrag", behaviours opzetten. Als de primary rij verwijderd, toegewezen, ongedeeld of aan een andere parent gekoppeld wordt, wat moet er met de onderliggende gekoppelde records gebeuren? Het standaard gedrag is reference, dus de link tussen 2 tabellen wordt verwijderd als de primary rij verwijderd wordt. Dus als een locatie verwijderd wordt, heb je ineens allemaal ongekoppelde desks. Je kunt een ForAll function gebruiken om die eerst te verwijderen, maar beter is het om het "parental type of behaviour for the relationship" in te stellen.

En je hebt dus ook de N-N relaties. Daar tussen zit een verborgen tabel (intersect table) die deze koppelingen maakt.
Dit wordt toegelicht met een video: link.

Hierna krijgen we een overzicht van de 1:N relatie. We zien de desks bij een locatie. Dit kun je doen met een filter, maar omdat je ook de .-notatie kunt gebruiken, hoef je niet de Filter(Desks,Location.Location=FilterLocation_1.Selected.Location) te doen, maar kun je dit met FilterLocation_1.Selected.Desks doen.

En ook het tonen van de Locatie bij een Desk kun je in plaats van een LookUp(Locations,Location=ThisItem.Location.Location).Address vervangen met een ThisItem.Location.Address
En zo kun je ook de naam van het primaire contact tonen: ThisItem.Location.'Primary Contact'.'Full Name'

Het tonen van de locaties om te zoeken in een Edit-Form kun je doen door een Choices([@Desks].contoso_Location) uit te voeren. En daar kun je dan weer een filter op toepassen: Filter(Choices[@Desks].contoso_Location), Status='Staus (Locations)'.Active)

Met Patch() kun je de waarde van een kolom instellen op een record van de primaire tabel, voorbeeld is Patch(Desks, ThisItem, {Location:FilterLocation_1.Selected})

Ook met Relate kun je wat koppelen (en met Unrelate ontkoppelen, let op: waarde wordt NULL, dus pas op voor "zwevende records").

Hierna krijgen we de N-op-N relatie. Een "pennenbakje" kan als feature aan meerdere desks gekoppeld zijn.
Met Concat(ThisItem.'Desk Features',Name,",") kun je komma-gescheiden als 1 tekst de gekoppelde items krijgen.

Het beheren van N-N relaties is complexer. Je kunt N-N in de veldlijst selecteren, als je het veld aan een formulier toevoegt dan maakt het systeem geen formules om de control te laten werken en je krijgt een foutmelding: "Card: Desk Features", met een rood rondje met wit kruis.

Hiervoor moet je naar de Avanced-tab en daar op Unlock klikken. Dan kun je zelf zaken aanpassen en zorg je dat in veld Items de waarde 'Desk Features' geplaatst wordt. Hier staat nog een opmerking bij, dat voorbeeld is voor het toevoegen. Voor het aanpassen moet je de DisplayProperty van de card wijzigen van View naar Edit.

Na het opslaan krijg je weer een foutmelding: An entry is required or has an invalid value. Please correct and try again. Dat los je op door bij het Update-property de waarde in te stellen op DataCardValue2.SelectedItems

Het werkt, maar de relaties tussen Desk en Desk Features wordt nog steeds niet gemaakt. Hiervoor moet je logica toevoegen op de OnSelect eigenschap.

  • sla de desk features die in de combo-box geselecteerd zijn als een collectie.
  • verstuur het formulier.
  • gebruik de opgeslagen collectie om de relaties op te slaan. Dat wordt weergegeven als:


ClearCollect(colAddDeskFeatures,DataCardValue2.SelectedItems);
SubmitForm(Form1_1);
ForAll(colAddDeskFeatures,Relate(Form1.LastSubmit.'Desk Features',ThisRecord));

De gebruikerservaring is gelijk aan de kolom van type Choices. Maar daarbij zijn de keuzes vastgelegd door de developer (wijzigen bijna niet), maar opties kunnen niet uitgeschakeld of afgeschermd worden.

Hierna gaan we nog een aantal voorbeelden uitvoeren.

  • Start hiervan is dit zip-bestand: link.
  • Je importeert deze app, koppelt vervolgens je eigen Dataverse connectie eraan.
  • Hierna laad je sample-data in.
  • Vervolgens start je de app.
  • Je maakt een aantal reserveringen aan.
  • Hierna voeg je en knop toe om te "boeken". Hieraan koppel je een Patch-functie om een rij in Reservation aan te maken.
  • Dan voeg je bij het overzicht van je reserveringen extra gegevens toe (telefoonnummer locatie, naam primair contact).
  • Daarna een Like-icoon toevoegen om je "favoriete desk" vast te leggen.
  • En nog wat "hot linking" om naast het filteren op locatie ook te kunnen filteren op features en zo de desks op die locatie met die features te zien.


Hierna de vragen, allemaal goed.