{"id":55000177,"date":"2019-04-01T00:00:00","date_gmt":"2020-03-27T19:37:36","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=177"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Entity_Framework_Der_ChangeTracker","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/Entity_Framework_Der_ChangeTracker\/","title":{"rendered":"Entity Framework: Der ChangeTracker"},"content":{"rendered":"<p><b>Wenn Sie Daten etwa aus den Tabellen einer Datenbank in ein Entity Data Model geladen haben, finden Sie dort einige Funktionen f&uuml;r den Umgang mit den enthaltenen Daten vor. Ein sehr wichtiges Element ist dabei der ChangeTracker. Auch wenn Sie mit der SaveChanges-Methode automatisch alle &Auml;nderungen im Entity Data Model erkennen und diese in die Datenbank &uuml;bertragen k&ouml;nnen, so treten doch F&auml;lle auf, in denen Sie zuvor pr&uuml;fen wollen, welche &Auml;nderungen &uuml;berhaupt im Entity Data Model vorgenommen wurden &#8211; und ob diese in die Datenbank &uuml;bernommen oder vielleicht sogar verworfen werden sollen.<\/b><\/p>\n<p>Wenn Sie eine Anwendung bauen, wie wir sie in den letzten Ausgaben verwendet haben, dann bezieht diese ihre Daten aus den Tabellen eines SQL Servers und stellt diese in einem Entity Data Model bereit. Die Elemente des Entity Data Models binden Sie dann an die Benutzeroberfl&auml;che und die dort befindlichen Steuer-elemente.<\/p>\n<p>Nun k&ouml;nnen nach dem Anzeigen der Daten in einem Fenster zum Bearbeiten verschiedene F&auml;lle auftreten: Sie &auml;ndern ein oder mehrere Felder eines Datensatzes, f&uuml;gen einen neuen Datensatz hinzu oder l&ouml;schen einen Datensatz. Diese &Auml;nderungen liegen dann im Entity Data Model vor, aber werden nicht automatisch in die Datenbank &uuml;bertragen. Das erledigen Sie erst, wenn Sie die <b>SaveChanges<\/b>-Methode des Datenbankkontextes aufrufen. <b>SaveChanges <\/b>ist effizient, denn es pr&uuml;ft, ob &Auml;nderungen vorliegen und speichert nur die ge&auml;nderten Elemente in der Datenbank.<\/p>\n<p>Was aber geschieht, wenn Sie beispielsweise erfahren wollen, ob an einem bestimmten Datensatz &Auml;nderungen vorgenommen wurden F&uuml;r ein Fenster mit Minimalanforderungen ben&ouml;tigen Sie diese Information nicht, denn Sie k&ouml;nnen die &Auml;nderungen ja einfach in der Datenbank speichern. Wenn Sie dem Benutzer jedoch ein paar weitere Features wie etwa eine Schaltfl&auml;che zum Verwerfen der &Auml;nderungen zur Verf&uuml;gung stellen wollen, kann es schon interessant sein, ob der Benutzer &uuml;berhaupt schon &Auml;nderungen am aktuellen Datensatz vorgenommen hat. Dabei k&ouml;nnten Sie die Information, ob der Datensatz bereits ge&auml;ndert wurde, etwa dazu nutzen, die <b>Abbrechen<\/b>&#8211; oder <b>Verwerfen<\/b>-Schaltfl&auml;che nur zu aktivieren, wenn der Benutzer bereits &Auml;nderungen vorgenommen hat &#8211; oder wenn er soeben einen neuen Datensatz angelegt hat, der ja mitunter auch verworfen werden k&ouml;nnte.<\/p>\n<p>Und hier kommt der <b>ChangeTracker <\/b>von Entity Framework ins Spiel. Dabei handelt es sich um eine Klasse, die zum Beispiel den Zugriff auf alle Elemente mit einem bestimmten Status zul&auml;sst &#8211; beispielsweise ge&auml;ndert oder nicht ge&auml;ndert. In diesem Artikel schauen wir uns nun an, wie Sie mit dem <b>ChangeTracker <\/b>von Entity Framework arbeiten k&ouml;nnen.<\/p>\n<h2>Beispielprojekt<\/h2>\n<p>Als Beispielprojekt verwenden wir ein Projekt auf Basis der Vorlage <b>Visual Basic|Windows Desktop|WPF-App <\/b>namens <b>ChangeTracker<\/b>. Dieser haben wir ein Entity Data Model mit der Methode aus der Artikelreihe <b>Von Access zu Entity Framework <\/b>hinzugef&uuml;gt und eine SQL Server-Datenbank damit erstellt. Um die SQL Server-Datenbank auf ihrem Rechner zu erstellen, rufen Sie die Anweisung <b>Update-Database <\/b>in der Paket-Manager-Konsole auf. Dadurch wird eine Datenbank auf Basis der in der Datei <b>App.config <\/b>angegebenen Verbindungszeichenfolge erstellt, die Sie gegebenenfalls noch anpassen k&ouml;nnen. Die verschiedenen Beispielcodes der folgenden Abschnitte finden Sie hinter den Ereignismethoden der Schaltfl&auml;chen des Fensters <b>MainWindow.xaml<\/b>.<\/p>\n<h2>Die ChangeTracker-Klasse<\/h2>\n<p>Die <b>ChangeTracker<\/b>-Klasse referenzieren &uuml;ber die gleichnamige Eigenschaft der Datenbankkontext-Klasse, die in unserem Beispielen meist <b>dbContext <\/b>genannt wird. Mit dieser Klasse k&ouml;nnen Sie den Zustand jedes der Elemente des aktuellen Datenbankkontexts nachverfolgen. Jeder der Eintr&auml;ge hat einen Wert f&uuml;r die Eigenschaft <b>EntityState<\/b>. Die m&ouml;glichen Werte lauten:<\/p>\n<ul>\n<li><b>Added<\/b>: Hinzugef&uuml;gtes Element, das noch nicht in der Datenbank existiert<\/li>\n<li><b>Modified<\/b>: Ge&auml;ndertes Element, dessen &Auml;nderungen noch nicht in die Datenbank &uuml;bertragen wurden<\/li>\n<li><b>Deleted<\/b>: Gel&ouml;schtes Element, das noch in der Datenbank existiert<\/li>\n<li><b>Unchanged<\/b>: Nicht ge&auml;ndertes Element<\/li>\n<li><b>Detached<\/b>: Nicht verbundenes, also nicht zu einem <b>DbSet <\/b>geh&ouml;rendes Element. Dieses wird auch nicht vom ChangeTracker verfolgt.<\/li>\n<\/ul>\n<h2>Beispiele zur ChangeTracker-Klasse<\/h2>\n<p>Wir schauen uns die verschiedenen Zust&auml;nde an einfachen Beispielen an. Dazu f&uuml;gen wir der Klasse <b>MainWindow.xaml.vb <\/b>zun&auml;chst die folgenden Namespaces hinzu:<\/p>\n<pre>Imports System.Data.Entity\r\nImports System.Data.Entity.Infrastructure<\/pre>\n<p>Danach erstellen wir die folgende Ereignismethode f&uuml;r die erste Schaltfl&auml;che <b>btnUnveraendert<\/b>. Hier f&uuml;llen wir die Variable <b>dbContext <\/b>mit einer neuen Instanz des Datenbankkontextes und f&uuml;llen das Objekt <b>Kunde <\/b>des Typs <b>Kunde <\/b>mit dem ersten Eintrag der Liste <b>Kunden <\/b>des Datenbankbankkontextes:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>btnUnveraendert_Click(sender<span style=\"color:blue;\"> As Object<\/span>, e<span style=\"color:blue;\"> As <\/span>RoutedEventArgs)\r\n     <span style=\"color:blue;\">Dim <\/span>dbContext<span style=\"color:blue;\"> As <\/span>BestellverwaltungContext\r\n     <span style=\"color:blue;\">Dim <\/span>Element<span style=\"color:blue;\"> As <\/span>EntityEntry\r\n     <span style=\"color:blue;\">Dim <\/span>Kunde<span style=\"color:blue;\"> As <\/span>Kunde\r\n     dbContext = <span style=\"color:blue;\">New<\/span> BestellverwaltungContext\r\n     Kunde = dbContext.Kunden.First()<\/pre>\n<p>Danach folgt der erste Zugriff auf den <b>ChangeTracker<\/b>. Dabei durchlaufen wir dessen <b>Entries<\/b>-Auflistung und referenzieren das aktuelle Element jeweils mit der Variablen <b>Element<\/b>, die &uuml;brigens den Typ <b>EntityEntry <\/b>aufweist (daf&uuml;r auch der Verweis auf den Namespace). Anschlie&szlig;end geben wir f&uuml;r jeden Eintrag zwei Informationen aus &#8211; den Namen des Elementtyps und den Zustand. Um den Namen des Elementtyps zu erhalten, referenzieren wir zun&auml;chst die in <b>Element <\/b>enthaltene Entit&auml;t mit der Eigenschaft <b>Entity <\/b>und ermitteln den Namen des Typs mit <b>GetType().Name<\/b>. Den Zustand dieses Eintrags liefert die Eigenschaft <b>State <\/b>des <b>EntityEntry<\/b>-Elements:<\/p>\n<pre>     For Each Element In dbContext.ChangeTracker.Entries\r\n         <span style=\"color:blue;\">Debug.Print<\/span>(\"Elementname: \" + Element.Entity.GetType().Name + \" Status: \" + Element.State.ToString())\r\n     <span style=\"color:blue;\">Next<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Das Ergebnis sieht schlie&szlig;lich wie in Bild 1 aus. Der Typ <b>Kunde <\/b>wird korrekt erkannt und auch der Status entspricht mit <b>Unchanged <\/b>den Erwartungen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_02\/pic_177_001.png\" alt=\"Ausgabe von Typ und Status einer Entit&auml;t\" width=\"649,559\" height=\"187,2191\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Ausgabe von Typ und Status einer Entit&auml;t<\/span><\/b><\/p>\n<h2>ChangeTracker verfolgt alle Elementtypen<\/h2>\n<p>Wir f&uuml;gen eine Variable f&uuml;r ein Element eines weiteren Elementtypen namens <b>Anrede <\/b>hinzu und lesen auch hier den ersten Eintrag aus  &#8211; in diesem Fall aus der Liste <b>Anreden<\/b>:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>Anrede<span style=\"color:blue;\"> As <\/span>Anrede\r\n...\r\nAnrede = dbContext.Anreden.First()<\/pre>\n<p>Die Ausgabe im Ausgabefenster sieht nach dem erneuten Start der Anwendung dem Bet&auml;tigen der Schaltfl&auml;che wie folgt aus:<\/p>\n<pre>Elementname: Kunde Status: Unchanged\r\nElementname: Anrede Status: Unchanged<\/pre>\n<p>Wir sehen also, dass die <b>Entries<\/b>-Auflistung der <b>ChangeTracker<\/b>-Klasse Elemente aller Typen umfasst &#8211; sie m&uuml;ssen nur in den Speicher geladen sein.<\/p>\n<h2>Ein Element l&ouml;schen<\/h2>\n<p>Im n&auml;chsten Beispiel wollen wir untersuchen, was beim L&ouml;schen eines Eintrags geschieht. Dazu legen wir eine neue Schaltfl&auml;che namens <b>btnGeloeschterEintrag <\/b>hinzu, f&uuml;r deren <b>Click<\/b>-Ereignis wir die folgende Ereignismethode hinterlegen:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>btnGeloeschterEintrag_Click(sender<span style=\"color:blue;\"> As Object<\/span>, e<span style=\"color:blue;\"> As <\/span>RoutedEventArgs)\r\n     <span style=\"color:blue;\">Dim <\/span>dbContext<span style=\"color:blue;\"> As <\/span>BestellverwaltungContext\r\n     <span style=\"color:blue;\">Dim <\/span>Bestellposition<span style=\"color:blue;\"> As <\/span>Bestellposition\r\n     <span style=\"color:blue;\">Dim <\/span>Element<span style=\"color:blue;\"> As <\/span>DbEntityEntry\r\n     dbContext = <span style=\"color:blue;\">New<\/span> BestellverwaltungContext\r\n     Bestellposition = dbContext.Bestellpositionen.First()\r\n     dbContext.Bestellpositionen.Remove(Bestellposition)\r\n     For Each Element In dbContext.ChangeTracker.Entries\r\n         MessageBox.Show(\"Elementname: \" + Element.Entity.GetType().Name + <span style=\"color:blue;\">vbCrLf<\/span> + \" Status: \" _\r\n             + Element.State.ToString())\r\n     <span style=\"color:blue;\">Next<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Hier laden wir nun das erste Element der Auflistung <b>Bestellpositionen<\/b>, da wir diese ohne Probleme l&ouml;schen k&ouml;nnen &#8211; die Eintr&auml;ge haben keine Beziehungen, deren Restriktion ein L&ouml;schen verhindern k&ouml;nnte. Dann l&ouml;schen wir dieses Element mit der <b>Remove<\/b>-Methode aus der Auflistung <b>Bestellpositionen<\/b>. Anschlie&szlig;end rufen wir wieder die gleiche <b>For Each<\/b>-Schleife &uuml;ber die <b>Entries<\/b>-Auflistung. Diesmal liefert die <b>State<\/b>-Eigenschaft den Wert <b>Deleted<\/b>.<\/p>\n<h2>Ein Element hinzuf&uuml;gen<\/h2>\n<p>Nun erstellen wir ein neues <b>Kunde<\/b>-Element, f&uuml;llen seine Eigenschaften und f&uuml;gen das <b>Kunde<\/b>-Element mit der <b>Add<\/b>-Methode zur Auflistung <b>Kunden <\/b>hinzu:<\/p>\n<pre>Kunde = <span style=\"color:blue;\">New<\/span> Kunde\r\n<span style=\"color:blue;\">With<\/span> Kunde\r\n     .Vorname = \"Andr&eacute;\"\r\n     .Nachname = \"Minhorst\"\r\n     .AnredeID = 1\r\n     .Strasse = \"Borkhofer Str. 17\"\r\n     .PLZ = \"47137\"\r\n     .Ort = \"Duisburg\"\r\n     .Land = \"Deutschland\"\r\n     .EMail = \"andre@minhorst.com\"\r\nEnd <span style=\"color:blue;\">With<\/span>\r\ndbContext.Kunden.Add(Kunde)\r\nElement = dbContext.ChangeTracker.Entries.First\r\nMessageBox.Show(\"Elementname: \" + Element.Entity.GetType().Name + <span style=\"color:blue;\">vbCrLf<\/span> + \" Status: \" + Element.State.ToString())<\/pre>\n<p>Hier lautet der Wert von <b>State <\/b>nun <b>Added<\/b>.<\/p>\n<h2>Ein Element &auml;ndern<\/h2>\n<p>Wir legen noch eine neue Schaltfl&auml;che an, mit der wir ein bestehendes Element &auml;ndern. Dazu weisen wir dem Feld <b>Vorname <\/b>des <b>Kunde<\/b>-Elements einen anderen Wert zu. Da wir wissen, dass wir gerade nur einen Eintrag ge&auml;ndert haben, durchlaufen wir keine Schleife mehr, sondern greifen &uuml;ber die <b>First<\/b>-Eigenschaft auf das ge&auml;nderte Element zu:<\/p>\n<pre>Kunde = dbContext.Kunden.First()\r\nKunde.Vorname = \"Andr&eacute;\"\r\nElement = dbContext.ChangeTracker.Entries.First\r\nMessageBox.Show(\"Elementname: \" + Element.Entity.GetType().Name + <span style=\"color:blue;\">vbCrLf<\/span> + \" Status: \" + Element.State.ToString())<\/pre>\n<p>In diesem Fall liefert die Eigenschaft <b>State<\/b> den Wert <b>Modified<\/b>.<\/p>\n<h2>Nicht verbundene Elemente<\/h2>\n<p>Es kann auch sein, dass Sie ein Element neu erstellen, aber dieses nicht mit der <b>Add<\/b>-Methode zur Auflistung des entsprechenden Elementtyps hinzuf&uuml;gen. Um zu untersuchen, welchen Zustand dieses Element hat und ob es vom <b>ChangeTracker <\/b>erfasst wird, m&uuml;ssen wir hier hier einen anderen Weg gehen. Wir finden n&auml;mlich, wie die zweite <b>MessageBox <\/b>zeigt, keinen Eintrag in der <b>ChangeTracker<\/b>-Liste <b>Entries <\/b>vor &#8211; das Ergebnis der <b>Count<\/b>-Eigenschaft ist <b>0<\/b>. Um ein <b>DbEntityEntry<\/b>-Element auf Basis des neuen <b>Kunde<\/b>-Objekts zu erstellen, greifen wir nun nicht auf die <b>Entries<\/b>-Liste der <b>ChangeTracker<\/b>-Klasse zu, sondern auf die <b>Entry<\/b>-Eigenschaft von <b>dbContext <\/b>f&uuml;r das <b>Kunde<\/b>-Objekt. F&uuml;r dieses erhalten wir dann als <b>State <\/b>den Wert <b>Detached<\/b>, also nicht verbunden:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>dbContext<span style=\"color:blue;\"> As <\/span>BestellverwaltungContext\r\n<span style=\"color:blue;\">Dim <\/span>Kunde<span style=\"color:blue;\"> As <\/span>Kunde\r\n<span style=\"color:blue;\">Dim <\/span>Element<span style=\"color:blue;\"> As <\/span>DbEntityEntry\r\ndbContext = <span style=\"color:blue;\">New<\/span> BestellverwaltungContext\r\nKunde = <span style=\"color:blue;\">New<\/span> Kunde\r\n<span style=\"color:blue;\">With<\/span> Kunde\r\n     .Vorname = \"Andr&eacute;\"\r\n     ...\r\nEnd <span style=\"color:blue;\">With<\/span>\r\nElement = dbContext.Entry(Kunde)\r\nMessageBox.Show(\"Elementname: \" + Element.Entity.GetType().Name + <span style=\"color:blue;\">vbCrLf<\/span> + \" Status: \" + Element.State.ToString())\r\nMessageBox.Show(\"Anzahl Elemente Changetracker: \" + dbContext.ChangeTracker.Entries.Count().ToString())<\/pre>\n<h2>Unterschied zwischen Entry(Element) und ChangeTracker.Entries<\/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\/55000177\/\">\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\/55000177?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\t\t\t\t\t<input type=\"hidden\" name=\"rcp_redirect\" value=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000177\/\"\/>\n\t\t\t\t\t\t\t\t<input type=\"hidden\" name=\"rcp_login_nonce\" value=\"33f7c20182\"\/>\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 Daten etwa aus den Tabellen einer Datenbank in ein Entity Data Model geladen haben, finden Sie dort einige Funktionen f&uuml;r den Umgang mit den enthaltenen Daten vor. Ein sehr wichtiges Element ist dabei der ChangeTracker. Auch wenn Sie mit der SaveChanges-Methode automatisch alle &Auml;nderungen im Entity Data Model erkennen und diese in die Datenbank &uuml;bertragen k&ouml;nnen, so treten doch F&auml;lle auf, in denen Sie zuvor pr&uuml;fen wollen, welche &Auml;nderungen &uuml;berhaupt im Entity Data Model vorgenommen wurden &#8211; und ob diese in die Datenbank &uuml;bernommen oder vielleicht sogar verworfen werden sollen.<\/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":[66022019,662019,44000021],"tags":[],"yst_prominent_words":[],"class_list":["post-55000177","post","type-post","status-publish","format-standard","hentry","category-66022019","category-662019","category-Entity_Framework"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000177","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=55000177"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000177\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000177"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000177"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000177"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000177"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}