{"id":55000088,"date":"2017-06-01T00:00:00","date_gmt":"2020-03-27T19:26:44","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=88"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"SQLiteDatenmodellierung_per_C","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/SQLiteDatenmodellierung_per_C\/","title":{"rendered":"SQLite-Datenmodellierung per C#"},"content":{"rendered":"<p><b>Wenn Sie eine SQLite-Datenbank von einer WPF\/C#-Anwendung aus nutzen, m&ouml;chten Sie gegebenenfalls einmal Tabellen in dieser Datenbank anlegen, &auml;ndern oder l&ouml;schen oder gar neue Datenbanken mit C# erstellen. Dies kann beispielsweise interessant werden, wenn Sie eine neue Version einer Anwendung ausliefern, aber der Benutzer die Daten in der Datenbank der vorherigen Version weiter nutzen m&ouml;chte. Dieser Artikel stellt die grundlegenden Vorgehensweisen f&uuml;r diese Arbeitsschritte vor.<\/b><\/p>\n<h2>NuGet-Paket f&uuml;r SQLite hinzuf&uuml;gen<\/h2>\n<p>Wenn Sie von einer C#-Anwendung aus &Auml;nderungen an einer SQLite-Datenbank vornehmen oder diese sogar erstellen wollen, ben&ouml;tigen Sie das NuGet-Paket mit den entsprechenden Erweiterungen. Dazu klicken Sie mit der rechten Maustaste auf das Projekt im Projektmappen-Explorer und w&auml;hlen den Kontextmen&uuml;-Eintrag <b>NuGet-Pakete verwalten&#8230; <\/b>aus. Im nun erscheinenden Bereich wechseln Sie auf Durchsuchen und suchen nach <b>SQLite<\/b>. Den nun auftauchenden Eintrag <b>System.Data.SQLite <\/b>k&ouml;nnen Sie dann ausw&auml;hlen und installieren.<\/p>\n<h2>SQLite-Befehle verf&uuml;gbar machen<\/h2>\n<p>In der Klasse, in der Sie die Befehle zum Erstellen und Anpassen von SQLite-Datenbanken unterbringen wollen, ben&ouml;tigen Sie zun&auml;chst einen Verweis auf den Namespace <b>System.Data.SQLite<\/b>, der erst nach dem Hinzuf&uuml;gen des oben genannten NuGet-Pakets vorfinden:<\/p>\n<pre>using System.Data.SQLite;<\/pre>\n<h2>Leere Datenbank erstellen<\/h2>\n<p>Um eine leere Datenbank zu erstellen, f&uuml;gen wir dem Fenster <b>MainWindow.xaml <\/b>ein Textfeld zur Eingabe des Datenbanknamens sowie eine Schaltfl&auml;che zum Erstellen der leeren Datenbankdatei hinzu. Diese Schaltfl&auml;che soll die folgende Methode ausl&ouml;sen:<\/p>\n<pre>private void btnCreateDatabase_Click(object sender, RoutedEventArgs e) {\r\n     string databaseFile = AppDomain.CurrentDomain.BaseDirectory + txtDatenbankname.Text;\r\n     File.Delete(databaseFile);\r\n     SQLiteConnection.CreateFile(databaseFile);\r\n     if (File.Exists(databaseFile)) {\r\n         MessageBox.Show(\"Leere Datenbank \\n\\n''\" + databaseFile + \"''\\n\\n wurde erstellt.\");\r\n     }\r\n}<\/pre>\n<p>Die Methode tr&auml;gt den Pfad der <b>.exe<\/b>-Datei plus den vom Benutzer gew&auml;hlten Datenbanknamen in die Variable <b>databaseFile <\/b>ein. Diese Datei wird, sofern vorhanden, gel&ouml;scht und dann mit der Methode <b>CreateFile <\/b>des Objekts <b>SQLiteConnection <\/b>neu erstellt. Dabei &uuml;bergeben Sie die Variable mit dem Datenbankpfad als Parameter. Die folgende <b>if<\/b>-Bedingung pr&uuml;ft, ob nach diesem Vorgang eine Datei mit dem angegebenen Namen vorhanden ist und zeigt in diesem Fall eine entsprechende Meldung an.<\/p>\n<h2>Neue Tabelle erstellen<\/h2>\n<p>Nun wollen wir der frisch angelegten Datenbank eine erste Tabelle hinzuf&uuml;gen. Das ist dann auch tats&auml;chlich der erste Inhalt der Datenbankdatei &#8211; diese weist nach dem Anlegen n&auml;mlich die Dateigr&ouml;&szlig;e <b>0 <\/b>auf (siehe Bild 1). Danach rufen wir mit der Tasten <b>btnCreateTable <\/b>die folgende Methode auf, die wieder den Pfad der <b>.exe<\/b>-Datei und den Dateinamen aus dem Textfeld in der Variablen <b>databaseFile <\/b>zusammensetzt. Dann erstellt sie ein neues Objekt des Typs <b>SQLiteConnection<\/b>, der sie als Konstruktor-Parameter eine Zeichenkette &uuml;bergibt, die aus <b>Data Source=<\/b>, dem Datenbankpfad und der zu verwenden Version besteht.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/pic_88_001.png\" alt=\"Frisch angelegte Datenbankdatei\" width=\"499,6607\" height=\"327,7774\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Frisch angelegte Datenbankdatei<\/span><\/b><\/p>\n<p>Die <b>Open<\/b>-Methode &ouml;ffnet die Verbindung zu dieser Datenbank. Dann schreibt die Methode eine <b>CREATE TABLE<\/b>-Anweisung, die eine neue Tabelle namens <b>Beispieltabelle <\/b>mit den beiden Feldern <b>id <\/b>und <b>Beispielstring <\/b>enth&auml;lt. Nun erstellt die Methode ein neues <b>SQLiteCommand<\/b>-Objekt und &uuml;bergibt die SQL-Anweisung aus der String-Variablen <b>sql <\/b>sowie das Verbindungsobjekt aus <b>connection <\/b>als Parameter. Die <b>ExecuteNonQuery<\/b>-Methode f&uuml;hrt die <b>CREATE TABLE<\/b>-Anweisung schlie&szlig;lich aus. Mit der <b>Close<\/b>-Methode schlie&szlig;en wir die Verbindung:<\/p>\n<pre>private void btnCreateTable_Click(object sender, RoutedEventArgs e) {\r\n     string databaseFile = AppDomain.CurrentDomain.BaseDirectory + txtDatenbankname.Text;\r\n     SQLiteConnection connection = new SQLiteConnection(\"Data Source=\" + databaseFile + \";Version=3;\");\r\n     connection.Open();\r\n     string sql = \"CREATE TABLE Beispieltabelle (id INT, Beispielstring VARCHAR(255))\";\r\n     SQLiteCommand command = new SQLiteCommand(sql, connection);\r\n     command.ExecuteNonQuery();\r\n     connection.Close();\r\n}<\/pre>\n<p>Ein Blick in den Windows Explorer zeigt, dass dies nicht spurlos an der Datenbankdatei vor&uuml;bergegangen ist: Diese hat nun immerhin eine Gr&ouml;&szlig;e von acht Kilobytes. Aber befindet sich auch die neue Tabelle darin Dies pr&uuml;fen wir mit dem Tool <b>SQLiteStudio<\/b>, das Sie kostenlos &uuml;ber das Internet herunterladen k&ouml;nnen. Mit dem Men&uuml;eintrag <b>Datenbank|Datenbank hinzuf&uuml;gen <\/b>&ouml;ffnen Sie den Dialog aus Bild 2. Hier w&auml;hlen Sie die soeben angelegte Datei aus und klicken nach dem Bet&auml;tigen von <b>Verbindung testen <\/b>auf die Schaltlf&auml;che <b>OK<\/b>.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/pic_88_002.png\" alt=\"Hinzuf&uuml;gen der Datenbank zum SQLiteStudio\" width=\"349,7625\" height=\"285,0928\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Hinzuf&uuml;gen der Datenbank zum SQLiteStudio<\/span><\/b><\/p>\n<p>Danach finden Sie im Hauptfenster von <b>SQLiteStudio <\/b>bereits die Datenbank mit der ersten Tabelle im Datenbank-Explorer vor (siehe Bild 3). Allerdings verf&uuml;gt das Feld <b>id<\/b> noch nicht &uuml;ber eine Prim&auml;rschl&uuml;ssel, aber das k&ouml;nnen wir ja gleich nachholen &#8211; indem wir die neue Tabelle ver&auml;ndern.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/pic_88_003.png\" alt=\"Die neue Tabelle im SQLiteStudio\" width=\"649,559\" height=\"471,9579\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Die neue Tabelle im SQLiteStudio<\/span><\/b><\/p>\n<h2>Tabelle mit Prim&auml;rschl&uuml;sselfeld erstellen<\/h2>\n<p>Im n&auml;chsten Beispiel wollen wir eine Tabelle erstellen und das <b>ID<\/b>-Feld direkt als Prim&auml;rschl&uuml;sselfeld kennzeichnen. Dazu f&uuml;gen wir der <b>CREATE TABLE<\/b>-Methode gleich das Schl&uuml;sselwort <b>PRIMARY KEY <\/b>f&uuml;r das Feld <b>ID <\/b>hinzu. Dazu nutzen wir prinzipiell die gleiche Methode wie f&uuml;r das vorherige Beispiel:<\/p>\n<pre>private void btnTabelleMitPKAnlegen_Click(object sender, RoutedEventArgs e) {\r\n     string databaseFile = AppDomain.CurrentDomain.BaseDirectory + txtDatenbankname.Text;\r\n     string connectionString = \"Data Source=\" + databaseFile + \";Version=3;\";\r\n     MessageBox.Show(connectionString);\r\n     SQLiteConnection connection = new SQLiteConnection(connectionString);\r\n     connection.Open();\r\n     string sql = \"CREATE TABLE BeispieltabelleMitPK (id INT PRIMARY KEY, Beispielstring VARCHAR(255))\";\r\n     SQLiteCommand command = new SQLiteCommand(sql, connection);\r\n     command = new SQLiteCommand(sql, connection);\r\n     command.ExecuteNonQuery();\r\n     connection.Close();\r\n}<\/pre>\n<p>Auch das liefert das gew&uuml;nschte Ergebnis, wie ein Blick in <b>SQLiteStudio<\/b> beweist (siehe Bild 4).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/pic_88_004.png\" alt=\"Tabelle mit Prim&auml;rschl&uuml;ssel im SQLiteStudio\" width=\"549,6265\" height=\"296,5911\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Tabelle mit Prim&auml;rschl&uuml;ssel im SQLiteStudio<\/span><\/b><\/p>\n<p>Nun habe ich allerdings beim Erstellen der neuen Tabelle bei Experimentieren vergessen, das Textfeld <b>txtDatenbankname <\/b>zu f&uuml;llen. Es gibt allerdings beim Durchlaufen der obigen Methode keinerlei Fehlermeldung &#8211; wie kann das sein Theoretisch d&uuml;rfte der Zugriff auf die Datenbank mit der <b>Open<\/b>-Methode doch gar nicht funktionieren, da die Datenbankdatei gar nicht vorhanden ist Doch das ist ein Fehlschluss: Dadurch, dass wir <b>txtDatenbankname <\/b>nicht gef&uuml;llt haben, &uuml;bergeben wir n&auml;mlich einen String wie den folgenden mit <b>connectionString <\/b>an die <b>Open<\/b>-Methode:<\/p>\n<pre>Data Source=C:\\Users\\User\\...\\bin\\Debug\\;Version=3;<\/pre>\n<p>Wenn wir nun in das Verzeichnis <b>&#8230;\\bin\\Debug <\/b>schauen, finden wir dort auch keine neue Datenbank etwa mit einem beim &Ouml;ffnen tempor&auml;r vergebenen Namen. Wenn wir allerdings eine Ebene nach oben gehen, also in das Verzeichnis <b>&#8230;\\bin<\/b>, finden wir die Situation aus Bild 5 vor. SQLite legt, wenn die in der Verbindungszeichenfolge f&uuml;r die <b>Open<\/b>-Methode angegebene Datenbankdatei noch nicht vorhanden ist, eine neue Datenbank an. In diesem Fall hat SQLite <b>Debug\\;Version=3;<\/b> als Dateinamen interpretiert und eine Datei namens <b>Debug;Version=3 <\/b>angelegt (das Backslash-Zeichen <b>\\ <\/b>wurde dabei als Escape-Zeichen f&uuml;r das Semikolon interpretiert). Die Gr&ouml;&szlig;e von <b>20 KB <\/b>zeigt an, dass hier auch gleich die gew&uuml;nschte Tabelle angelegt wurde.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2017_03\/pic_88_005.png\" alt=\"Eine Datenbankdatei namens Debug;Version=3\" width=\"549,6265\" height=\"370,5119\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Eine Datenbankdatei namens Debug;Version=3<\/span><\/b><\/p>\n<h2>Autowert definieren<\/h2>\n<p>Beim Einf&uuml;gen von Datens&auml;tzen m&uuml;ssen wir uns Gedanken darum machen, auf welche Weise der Wert des Prim&auml;rschl&uuml;sselfeldes definiert wird. Unter Access wurde das immer einfach durch Festlegen der Eigenschaft <b>Autowert <\/b>f&uuml;r das betroffene Feld erledigt. Unter SQLite ist das auch nicht viel anders: Hier f&uuml;gen Sie hinter dem <b>PRIMARY KEY<\/b>-Schl&uuml;sselwort einfach noch <b>AUTOINCREMENT <\/b>ein (siehe Methode <b>btnTabelleMitAutowertAnlegen_Click<\/b>):<\/p>\n<pre>CREATE TABLE BeispieltabelleMitAutowert(ID INTEGER PRIMARY KEY AUTOINCREMENT, ...)<\/pre>\n<p>SQLite hat hier allerdings eine etwas andere Philosophie als andere Datenbanksysteme: Sie m&uuml;ssen gar nicht unbedingt eine Autoincrement-Funktion definieren, sondern k&ouml;nnen das Prim&auml;rschl&uuml;sselfeld auch einfach nur als <b>INTEGER PRIMARY KEY <\/b>definieren. Wenn Sie dann beim Neuanlegen eines Datensatzes keinen Wert f&uuml;r das Prim&auml;rschl&uuml;sselfeld angeben, f&uuml;gt SQLite automatisch einen entsprechend ermittelten Wert ein. Gegen&uuml;ber anderen Datenbanksystemen haben Sie so die Wahl, ob Sie das System einen Prim&auml;rschl&uuml;sselwert ausw&auml;hlen lassen wollen oder ob Sie diesen selbst vergeben wollen. Mehr dazu erfahren Sie weiter unten unter <b>Datens&auml;tze einf&uuml;gen<\/b>.<\/p>\n<h2>Pr&uuml;fen, ob Datenbank vorhanden ist<\/h2>\n<p>Wir wollen an dieser Stelle den Benutzer darauf hinweisen, dass die Datenbank noch nicht vorhanden ist und die Methode abbrechen. Das erledigen wir mit einer entsprechenden <b>if<\/b>-Bedingung:<\/p>\n<pre>private void btnTabelleMitPKAnlegen_Click(object sender, RoutedEventArgs e) {\r\n     string databaseFile = AppDomain.CurrentDomain.BaseDirectory + txtDatenbankname.Text;\r\n     if (!File.Exists(databaseFile)) {\r\n         MessageBox.Show(\"Die Datenbank \\n\\n''\" + databaseFile + \"''\\n\\nist nicht vorhanden.\");\r\n     }\r\n     else {\r\n        \/\/Tabelle anlegen\r\n     }\r\n}<\/pre>\n<h2>Herstellen einer Verbindung in eigener Methode<\/h2>\n<p>In den bisherigen Beispielen haben wir jeweils einige Anweisungen eingebaut, welche die Verbindung herstellen und mit der Variablen <b>connection <\/b>referenzieren. Damit wir diese Zeilen nicht in jeder neuen Methode erneut schreiben m&uuml;ssen, gliedern wir diese in eine eigene Methode aus und erweitern deren Funktionsumfang gleich ein wenig.<\/p>\n<p>Die neue Methode hei&szlig;t VerbindungOeffnen und erwartet den Pfad zur Datenbankdatei als Parameter (<b>datenbankpfad<\/b>) sowie einen Boolean-Wert namens <b>datenbankErstellen<\/b>, der angibt, ob die Datenbank erstellt werden soll, wenn Sie noch nicht vorhanden ist. Die Methode stellt die Boolean-Variable <b>datenbankExistiert <\/b>zun&auml;chst auf <b>true <\/b>ein. Dann pr&uuml;ft sie, ob die mit <b>datenbankpfad <\/b>angegebene Datei existiert. Falls nicht, wird <b>datenbankExistiert <\/b>auf <b>false <\/b>eingestellt und eine Meldung ausgegeben, dass die Datenbank nicht vorhanden ist. Falls die Datenbank existiert, baut die Methode in der zweiten <b>if<\/b>-Bedingung eine Verbindungszeichenfolge zusammen, erstellt ein <b>SQLiteConnectionString<\/b>-Objekt auf Basis dieser Verbindung und &ouml;ffnet diese mit der <b>Open<\/b>-Methode. Die Verbindung wird dann als R&uuml;ckgabewert zur&uuml;ckgeliefert. Sollte <b>datenbankExistiert <\/b>den Wert <b>false <\/b>enthalten, liefert die Methode den Wert <b>null <\/b>zur&uuml;ck:<\/p>\n<pre>private SQLiteConnection VerbindungOeffnen(string datenbankpfad, bool datenbankErstellen = false) {\r\n     bool datenbankExistiert = true;\r\n     if (!File.Exists(datenbankpfad)) {\r\n         if (!datenbankErstellen) {\r\n             datenbankExistiert = false;\r\n             MessageBox.Show(\"Die Datenbank \\n\\n''\" + datenbankpfad+ \"''\\n\\nist nicht vorhanden.\");\r\n         }\r\n     }\r\n     if (datenbankExistiert) {\r\n         string connectionString = \"Data Source=\" + datenbankpfad + \";Version=3;\";\r\n         SQLiteConnection connection = new SQLiteConnection(connectionString);\r\n         connection.Open();\r\n         return connection;\r\n     }\r\n     else {\r\n         return null;\r\n     }\r\n}<\/pre>\n<h2>Pr&uuml;fen, ob Tabelle vorhanden ist<\/h2>\n<div class=\"rcp_restricted\"><p><span style=\"color: #ff0000;\">M&ouml;chten Sie weiterlesen? Dann l&ouml;sen Sie Ihr Ticket!<\/span><br \/>\n<span style=\"color: #ff0000;\">Hier geht es zur Bestellung des Jahresabonnements des Magazins <strong>Visual Basic Entwickler<\/strong>:<\/span><br \/>\n<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/shop.minhorst.com\/magazine\/363\/visual-basic-entwickler-jahresabonnement?c=77\">Zur Bestellung ...<\/a><\/span><br \/>\n<span style=\"color: #ff0000;\">Danach greifen Sie sofort auf <strong>alle rund 200 Artikel<\/strong> unseres Angebots zu - auch auf diesen hier!<\/span><br \/>\n<span style=\"color: #000000;\">Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:<\/span><\/p>\n<\/div>\n\n\t\n\t<form id=\"rcp_login_form\"  class=\"rcp_form\" method=\"POST\" action=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000088\/\">\n\n\t\t\n\t\t<fieldset class=\"rcp_login_data\">\n\t\t\t<p>\n\t\t\t\t<label for=\"rcp_user_login\">Username or Email<\/label>\n\t\t\t\t<input name=\"rcp_user_login\" id=\"rcp_user_login\" class=\"required\" type=\"text\"\/>\n\t\t\t<\/p>\n\t\t\t<p>\n\t\t\t\t<label for=\"rcp_user_pass\">Password<\/label>\n\t\t\t\t<input name=\"rcp_user_pass\" id=\"rcp_user_pass\" class=\"required\" type=\"password\"\/>\n\t\t\t<\/p>\n\t\t\t\t\t\t<p>\n\t\t\t\t<input type=\"checkbox\" name=\"rcp_user_remember\" id=\"rcp_user_remember\" value=\"1\"\/>\n\t\t\t\t<label for=\"rcp_user_remember\">Remember me<\/label>\n\t\t\t<\/p>\n\t\t\t<p class=\"rcp_lost_password\"><a href=\"\/data\/wp\/v2\/posts\/55000088?rcp_action=lostpassword\"><\/a><\/p>\n\t\t\t<p>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_action\" value=\"login\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_redirect\" value=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000088\/\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_login_nonce\" value=\"122f66fc6a\"\/>\n\t\t\t\t<input id=\"rcp_login_submit\" class=\"rcp-button\" type=\"submit\" value=\"Login\"\/>\n\t\t\t<\/p>\n\t\t\t\t\t<\/fieldset>\n\n\t\t\n\t<\/form>\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wenn Sie eine SQLite-Datenbank von einer WPF\/C#-Anwendung aus nutzen, m&ouml;chten Sie gegebenenfalls einmal Tabellen in dieser Datenbank anlegen, &auml;ndern oder l&ouml;schen oder gar neue Datenbanken mit C# erstellen. Dies kann beispielsweise interessant werden, wenn Sie eine neue Version einer Anwendung ausliefern, aber der Benutzer die Daten in der Datenbank der vorherigen Version weiter nutzen m&ouml;chte. Dieser Artikel stellt die grundlegenden Vorgehensweisen f&uuml;r diese Arbeitsschritte vor.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[662017,66032017,44000008,44000026,44000006,44000028],"tags":[],"yst_prominent_words":[],"class_list":["post-55000088","post","type-post","status-publish","format-standard","hentry","category-662017","category-66032017","category-Datenzugriffstechnik","category-Outlook_programmieren","category-SQL_Server_und_Co","category-Word_programmieren"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000088","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/comments?post=55000088"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000088\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000088"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000088"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000088"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000088"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}