Beispieldaten generieren mit .NET und Bogus

Das Produzieren von Beispieldaten ist immer wieder eine mühselige Aufgabe. Beispieldaten benötigen Sie, um beim Entwickeln neuer Anwendungen die Funktionen zu testen, die mit der Anzeige, dem Bearbeiten oder Löschen von Daten zusammenhängen. Und auch zum Testen des Hinzufügens von Daten benötigen Sie gegebenenfalls schon Daten in verknüpften Tabellen zur Auswahl. Unter .NET gibt es verschiedene Bibliotheken, die das Generieren von Beispieldaten erleichtern. Leider sind diese nicht so ohne Weiteres unter Access verfügbar. Zum Glück gibt es Tools, mit denen Sie diese Bibliotheken dennoch für Ihre Zwecke einsetzen können. In diesem Beitrag nutzen wir den Editor LINQPad, um Beispieldaten mit der Bogus-Bibliothek zu erzeugen und diese dann mit der Bibliothek LINQ to DB den Tabellen einer Beispieldatenbank hinzuzufügen.

Vorbereitungen

Für die beschriebenen Techniken benötigen Sie die Entwicklungsumgebung LINQPad sowie die Datenzugriffsbibliothek LINQ to DB. Wie Sie diese beiden herunterladen, installieren und verwenden, beschreiben wir im Beitrag Datenzugriff mit .NET, LINQPad und LINQ to DB (www.access-im-unternehmen.de/1358).

Wie Sie diese beiden nutzen, um mit einer weiteren Bibliothek namens Bogus zufällige Beispieldaten für eine Datenbank zu erzeugen, zeigen wir im vorliegenden Beitrag.

Bogus zum Projekt hinzufügen

Zum Ermitteln der Beispieldaten, die wir zu den Tabellen der Anwendung hinzufügen wollen, nutzen wir die bereits eingangs erwähnte Bibliothek Bogus.

Diese müssen wir genau wie LINQ to DB zunächst verfügbar machen. Dazu klicken Sie unter LINQPad mit der rechten Maustaste auf den Registerreiter des Query-Bereichs und wählen den Eintrag Query Properties… aus (siehe Bild 1).

Aufrufen des Dialogs Query Properties per Kontextmenü

Bild 1: Aufrufen des Dialogs Query Properties per Kontextmenü

Im nun erscheinenden Dialog Query Properties klicken Sie auf die Schaltfläche Add NuGet… und geben im folgenden Dialog unter Search online den Suchbegriff Bogus ein. Den nun angezeigten Eintrag aus Bild 2 fügen Sie dann mit einem Klick auf die Schaltfläche Add to Query hinzu.

Hinzufügen des Bogus-Pakets

Bild 2: Hinzufügen des Bogus-Pakets

Es erscheint nun ein neuer Eintrag im linken Bereich des Dialogs LINQPad NuGet Manager. Hier klicken Sie noch auf Add namespaces (siehe Bild 3).

Hinzufügen des Bogus-Namespaces

Bild 3: Hinzufügen des Bogus-Namespaces

Dies öffnet einen weiteren Dialog namens Add Namespaces From NuGet Assemblies. Hier wählen Sie den Eintrag Bogus aus und klicken auf OK (siehe Bild 4).

Hinzufügen eines Verweises auf den Bogus-Namespace

Bild 4: Hinzufügen eines Verweises auf den Bogus-Namespace

Nachdem Sie diesen Dialog und auch den Dialog LINQPad NuGet Manager geschlossen haben, finden Sie im Dialog Query Properties unter Additional References den Eintrag Bogus vor (siehe Bild 5).

Der Verweis auf den Bogus-Namespace

Bild 5: Der Verweis auf den Bogus-Namespace

Damit sind die Vorbereitungen abgeschlossen und wir können uns dem Einsatz von Bogus zum Generieren von Beispieldaten zuwenden.

Vorweg: Anreden anlegen

Einen Schritt erledigen wir allerdings noch vorneweg – das Anlegen der Datensätze in der Tabelle tblAnreden. Für diese benötigen wir keinen Zufallsgenerator und somit auch nicht die Bibliothek Bogus. Wir fügen die Anreden einfach mit der folgenden Prozedur hinzu:

Public Sub AnredenAnlegen
     Dim objUserQuery As UserQuery
     Dim objAnrede As tblAnreden
     objUserQuery = tblAnreden.DataContext
     objAnrede = New tblAnreden 
     With objAnrede 
         .ID = 1
         .Anredebezeichnung = "Herr"
     End With
     objUserQuery.Insert(objAnrede)
     objAnrede = New tblAnreden()
     With objAnrede
         .ID = 2
         .Anredebezeichnung = "Frau"
     End With
     objUserQuery.Insert(objAnrede)
End Sub

Den Code können wir mit Visual Basic übrigens auch wie folgt schreiben und sparen dabei nicht nur eine Variable, sondern auch einige Zeilen Code:

Public Sub AnredenAnlegen
     Dim objUserQuery As UserQuery
     objUserQuery = tblAnreden.DataContext
     objUserQuery.Insert(New tblAnreden With {.ID = 1,  .Anredebezeichnung = "Herr"})
     objUserQuery.Insert(New tblAnreden With {.ID = 2,  .Anredebezeichnung = "Frau"})
End Sub

Damit wir immer mit einer frisch aufgesetzten Tabelle tblAnreden starten, können wir zuvor die vorhandenen Anreden löschen:

Public Sub AnredenLoeschen
     Dim objUserQuery As UserQuery
     objUserQuery = tblAnreden.DataContext
     objUserQuery.Execute("DELETE FROM tblAnreden")
End Sub

Und schließlich geben wir die frisch erzeugten Anreden nachher einmal im Direktbereich von LINQPad aus:

Public Sub AnredenAusgeben
     Dim objAnrede As tblAnreden
     For Each objAnrede In tblAnreden
         Debug.Print(objAnrede.ID & " "  & objAnrede.Anredebezeichnung)
     Next objAnrede
End Sub

Zufallsdaten mit Bogus ermitteln

Bogus bietet verschiedene Klassen, die Funktionen zum Erstellen von Zufallsdaten thematisch zusammenfassen. Diese werden unter folgendem Link ausführlicher beschrieben:

https://github.com/bchavez/Bogus#bogus-api-support

Es gibt die folgenden Klassen:

  • Address: Liefert verschiedene Eigenschaften von Adressen wie Straße, PLZ, Ort und Land, aber auch beispielsweise Höhen- und Breitengrade oder Angaben wie Himmelsrichtungen.
  • Commerce: Interessant für alles, was mit dem Handel zu tun hat. Bietet Daten wie Produktnamen, Farben, Adjektive oder Materialien, Preise, Werte für Barcodes oder Kategorien und Abteilungen.
  • Company: Liefert Firmennamen, Gesellschaftsformen und Phrasen zu Unternehmen
  • Database: Liefert Feldnamen, Datentypen und weitere Datenbank-relevante Informationen
  • Date: Liefert Datumsangaben in verschiedenen Bereichen sowie Monate oder Wochentage
  • Finance: Gibt beispielsweise IBANs aus, wobei Sie festlegen können, aus welchem Land diese stammen und ob diese formatiert sein sollen. Außerdem liefert diese Klasse Geldbeträge, Transaktionstypen, Währungen, Kreditkartennummern, Prüfziffern und vieles mehr.
  • Hacker: Liefert zufällige Abkürzungen, Adjektive, Nomen, Verben oder komplette Phrasen, allerdings alles nur auf Englisch.
  • Images: Hiermit können Sie beispielsweise URLs zum Download von Bildern abfragen, welche Bilder in den angegebenen Dimensionen liefern.
  • Internet: Erstellt E-Mail-Adressen, Benutzernamen, Domainnamen, Domainendungen, Portnummern, IP-Adressen, Kennwörter und vieles mehr.
  • Lorem: Bietet einige Zufallsdaten rund um die Erstellung von Texten. Hierbei können Sie einzelne Wörter, Absätze, Buchstaben, Sätze et cetera generieren lassen – allerdings nur auf Lateinisch!
  • Name: Liefert Vornamen, Nachnamen, komplette Namen, aber auch Berufsbezeichnungen
  • Phone: Liefert Telefonnummern
  • Rant: Liefert Reviews, allerdings nur auf Englisch
  • System: Liefert Dateinamen, Verzeichnisse (nur im Unix-Format), Dateiendungen, Versionsnummern, Texte von Ausnahmen, Fahrzeugnummern
  • Vehicle: Liefert Fahrzeughersteller, -modelle und -typen, VINs (Fahrzeugnummern) und Kraftstoffarten
  • Random: Liefert Zufallswerte für die verschiedenen Datentypen und in den angegebenen Bereichen

Zufallsdaten mit der Faker-Klasse

Mit den in den Klassen enthaltenen Funktionen können Sie die verschiedensten Daten ermitteln. Um dies auszuprobieren, erstellen Sie einfach eine neues Objekt auf Basis der Klasse Bogus.Faker und greifen dann direkt auf die Klassen aus der obigen Auflistung und die darin enthaltenen Funktionen zu.

Im folgenden Beispiel schreiben wir den Code direkt in die Main-Klasse der LINQPad-Datei:

Sub Main
     Dim objFaker As New Bogus.Faker
     Debug.Print(objFaker.Name.FirstName)
End Sub

Dies gibt einfach einen zufällig gewählten Nachnamen im Direktbereich aus. Auf die gleiche Weise probieren Sie auch die anderen Funktionen dieser und anderer Klassen aus.

Adressdaten für Deutschland

Beim Ausprobieren von Funktionen wie Address.Street-Address, Address.ZipCode oder Address.City werden Sie feststellen, dass die Daten sich auf englische Adressen beziehen.

Sie können allerdings leicht auf deutsche Anschriften umschwenken, indem Sie beim Erstellen der Faker-Klasse den Wert „de“ als Parameter übergeben. Die folgenden Zeilen liefern beispielsweise direkt deutsche Namen und Adressdaten:

Dim objFaker As New Bogus.Faker("de")
Debug.Print(objFaker.Name.FirstName)
Debug.Print(objFaker.Address.StreetAddress)
Debug.Print(objFaker.Address.ZipCode)
Debug.Print(objFaker.Address.City)

Kunden anlegen

Nachdem Sie aus dem Beitrag Datenzugriff mit .NET, LINQPad und LINQ to DB (www.access-im-unternehmen.de/1358) wissen, wie Sie neue Datensätze mit den gewünschten Feldwerten zu einer Tabelle wie tblKunden hinzufügen, haben Sie nun prinzipiell alle Techniken zum Erstellen von auf Zufallsdaten basierenden Datenbankinhalten zur Hand.

Sie brauchen die Anweisungen zum Füllen der Felder nur noch mit den oben vorgestellten Funktionen der verschiedenen Klassen des Bogus.Faker-Objekts zu füllen.

Dann müssten wir allerdings für jeden Kunden ein neues Bogus.Faker-Objekt erstellen. Das brauchen wir jedoch nur ein einziges Mal zu tun, denn die Bogus.Faker-Klasse bietet eine Methode namens Generate an. Mit der können Sie, wenn Sie für den Parameter einen Zahlenwert angeben, eigentlich sogar gleich mehrere Objekte gleichzeitig erzeugen, aber diese können wir im aktuellen Kontext nicht verarbeiten. Also nutzen wir die Generate-Methode nur zum Erstellen eines Kunden gleichzeitig.

Bevor wir mit dem eigentlichen Code zum Erstellen einsteigen, deklarieren wir noch eine Enum-Auflistung für das Geschlecht – wozu wir diese benötigen, erläutern wir anschließend:

Public Enum Gender
     Male = 0
     Female = 1
End Enum

Die Prozedur KundenAnlegen erwartet die Anzahl der anzulegenden Kunden als Parameter. Dann deklariert sie die benötigten Variablen:

Public Sub KundenAnlegen(intMenge As Int32)
     Dim Beispielkunde As New tblKunden
     Dim objUserQuery As UserQuery
     Dim i As Int32
     Dim intGender As int32

Sie erstellt dann ein UserQuery-Objekt auf Basis der Tabelle tblKunden und ein neues Bogus.Faker-Objekt, dem Sie die Klasse tblKunden als Typ zuweisen.

Außerdem fügen wir noch den Wert „de“ als Parameter an, damit Bogus deutsche Daten liefert:

     objUserQuery = tblKunden.DataContext
     Dim objFaker As New Bogus.Faker(Of tblKunden)("de")

Dann folgt ein Teil, von dem nur die inneren Zeilen interessant sind – und mit dem wir die Regeln festlegen, nach denen wir neue Objekte des Typs tblKunden füllen.

Wichtig ist nur, dass Sie wissen, dass der Buchstabe k für das tblKunden-Objekt steht und f für das Bogus.Faker-Objekt. In der ersten Anweisung nutzen wir die Funktion PickRandom, um zufällig einen der beiden Werte der Enumeration Gender zu ermitteln (also 0 für männlich und 1 für weiblich) und schreiben das Ergebnis in die Variable intGender:

     objFaker.Rules(Function(f, k)
         intGender = f.PickRandom(Of Gender)

Diesen Wert benötigen wir anschließend gleich zwei Mal. Als Erstes addieren wir den Wert 1 hinzu und tragen das Ergebnis für die Eigenschaft AnredeID ein, von der wir wissen, dass der Wert 1 der Anrede Herr und der Wert 2 der Anrede Frau entspricht:

             k.AnredeID = intGender + 1

Dann übergeben wir intGender als Parameter der Funktion FirstName zum Ermitteln eines zufälligen Vornamens. Durch diesen Parameter legen wir fest, ob FirstName einen männlichen oder einen weiblichen Nachnamen liefert:

             k.Vorname = f.Name.FirstName(intGender)

Die übrigen Zeilen legen fest, aus welchen Funktionen und Klassen von Bogus.Faker die Daten für die übrigen Felder bezogen werden sollen:

             k.Nachname = f.Name.LastName()
             k.Strasse = f.Address.StreetAddress
             k.PLZ = f.Address.ZipCode
             k.Ort = f.Address.City
             k.Land = f.Address.Country
             k.EMail = f.Internet.Email
             k.Telefon = f.Phone.PhoneNumber
             k.Telefax = f.Phone.PhoneNumber
         End Function)

Damit haben wir die Vorlage für das Erstellen von Elementen des Typs tblKunden definiert.

Damit können wir nun in eine For…Next-Schleife einsteigen, welche die Werte von 1 bis zur Anzahl der zu erstellenden Elemente aus dem Parameter intMerge durchläuft. Innerhalb der Schleife erstellen wir mit der Generate-Methode auf Basis des objFaker-Objekts ein neues Element des Typs tblKunden und referenzieren es mit der Variablen Beispielkunde.

Diesem weisen wir dann noch den Wert aus der Laufvariablen i für das Feld ID hinzu und speichern es mit der Insert-Methode in dem mit objUserQuery referenzierten UserQuery-Objekt auf Basis der Tabelle tblKunden:

     For i = 1 To intMenge
         Beispielkunde = objFaker.Generate
         Beispielkunde.ID = i
         objUserQuery.Insert(Beispielkunde)
     Next 
End Sub

Die so erzeugten Kunden können Sie sich in der Beispieldatenbank ansehen oder Sie lassen sich diese mit einer einfachen Prozedur in LINQPad ausgeben:

Public Sub KundenAusgeben
     Dim objKunde As tblKunden
     For Each objKunde In tblKunden
         Debug.Print(objKunde.ID & " " & objKunde.AnredeID  & " " & objKunde.Vorname & " "  & objKunde.Nachname & " "  & objKunde.Strasse & " "  & objKunde.PLZ & " " & objKunde.Ort)
     Next objKunde
End Sub

Damit wir immer frisch loslegen können, erstellen wir noch eine Prozedur zum Löschen der bereits vorhandenen Kunden:

Public Sub KundenLoeschen
     Dim objUserQuery As UserQuery
     objUserQuery = tblKunden.DataContext
     objUserQuery.Execute("DELETE FROM tblKunden")
End Sub

Wenn Sie nun noch die folgenden Prozeduraufrufe in der Hauptmethode Main platzieren, erstellt diese die Daten in den Tabellen tblAnreden und tblKunden nach dem Löschen jeweils neu und gibt diese im Direktbereich von LINQPad aus:

Sub Main
     KundenLoeschen
     AnredenLoeschen
     AnredenAnlegen
     AnredenAusgeben
     KundenAnlegen(10)
     KundenAusgeben
End Sub

Beispieldaten für umfangreicheres Datenmodell

Nachdem wir uns die Grundlagen angesehen haben, wollen wir nun noch ein etwas umfangreicheres Datenmodell mit Beispieldaten füllen.

Dabei wollen wir die gängigsten Beziehungstypen abdecken – also 1:n- und m:n-Beziehungen. Dazu schauen wir uns das Datenmodell aus Bild 6 an. Die Reihenfolge beim Befüllen der Tabellen sieht wie folgt aus:

Datenmodell zum Füllen mit Beispieldaten

Bild 6: Datenmodell zum Füllen mit Beispieldaten

  • tblAnreden (enthält keine Fremdschlüsselfelder)
  • tblProdukte (enthält keine Fremdschlüsselfelder)
  • tblKunden (verweist nur auf Tabelle tblAnreden)
  • tblBestellungen (verweist nur auf Tabelle tblKunden)
  • tblBestellpositionen (verweist auf die Tabellen tblBestellungen und tblProdukte)

Dies ist die Reihenfolge zum Füllen mit Daten. Wenn wir die Tabellen vor dem Füllen mit Beispieldaten leeren wollen, müssen wir das in umgekehrter Reihenfolge erledigen – zumindest, wenn referenzielle Integrität ohne Löschweitergabe aktiviert ist und beispielsweise das Löschen von Daten aus der Tabelle tblAnreden nicht möglich ist, wenn es noch Datensätze in der Tabelle tblKunden gibt, die noch mit den zu löschenden Daten verknüpft sind.

Hinzufügen von Produkten

Die Produkte-Tabelle haben wir mit einem speziellen Feature ausgestattet. Es enthält ein Anlage-Feld zum Speichern von Bildern. Wir wollen sehen, ob und wie sich das füllen lässt.

Dazu testen wir es zunächst einmal mit der folgenden Version:

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar