{"id":55000024,"date":"2016-02-01T00:00:00","date_gmt":"2020-03-27T19:17:30","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=24"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Datenzugriff_mit_ADONET_Teil_2","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/Datenzugriff_mit_ADONET_Teil_2\/","title":{"rendered":"Datenzugriff mit ADO.NET, Teil 2"},"content":{"rendered":"<p><b>Im ersten Teil unserer Artikelreihe zum Thema ADO.NET haben wir uns angesehen, wie Sie mit dem DataReader-Objekt auf die Daten einer Tabelle zugreifen und wie Sie mit dem Command-Objekt Aktionsabfragen durchf&uuml;hren k&ouml;nnen. Im vorliegenden Teil sehen wir uns an, wie Sie mit dem DataAdapter-Objekt auf die Daten einer Datenbank zugreifen und das DataSet- und das DataTable-Objekt einsetzen, um verbindungslos mit den Daten einer Datenbank zu arbeiten.<\/b><\/p>\n<p>Die im ersten Teil dieser Artikelreihe vorgestellten Techniken f&uuml;r den Zugriff auf die Daten einer Datenbank erforderten eine ge&ouml;ffnete Verbindung. So etwas ist in einer Desktopdatenbank etwa auf Basis von Microsoft Access kein Problem. Etwas kritischer wird es schon, wenn Sie Access in einer Mehrbenutzerumgebung einsetzen &#8211; und vor allem dann, wenn die Anwendung &uuml;ber das Internet &uuml;ber die anzuzeigenden oder zu bearbeitenden Daten zugreift. In Zeiten der Mehrbenutzer-, Internet- und mobilen Anwendungen ben&ouml;tigen wir daher verbindungslose Zugriffstechnologien.<\/p>\n<p>Die unterst&uuml;tzt ADO.NET durch einige weitere Objekte, welche nach Wunsch mit den Daten einer oder mehrerer Tabellen oder Abfragen der Datenbank gef&uuml;llt werden. Der Benutzer zeigt die Daten an, l&ouml;scht, bearbeitet oder erweitert sie und st&ouml;&szlig;t dann den Speichervorgang f&uuml;r die Daten an. Daraufhin wird erneut eine Verbindung ge&ouml;ffnet und die ge&auml;nderten Daten werden zur&uuml;ck in die Datenbank geschrieben. Wie dies gelingt, schauen wir uns weiter unten an. Vorher jedoch noch einige Erg&auml;nzungen zum ersten Teil dieser Artikelreihe.<\/p>\n<h2>Verbindungszeichenfolge einfach festlegen<\/h2>\n<p>Wer sich mit dem Zusammenstellen der Zeichenkette f&uuml;r die Verbindungszeichenfolge schwer tut und\/oder Eingabefehler bei der Benennung der Parameter vermeiden will, kann auch ein Objekt namens <b>ConnectionStringBuilder <\/b>verwenden. Dieses gibt es ebenso wie die Objekte <b>Connection<\/b>, <b>Command <\/b>et cetera jeweils mit entsprechendem Pr&auml;fix f&uuml;r die verschiedenen ADO.NET-Klassen wie <b>System.Data.OLEDB<\/b>, <b>System.Data.ODBC<\/b>, <b>System.Data.SQL <\/b>und so weiter. Da wir aktuell noch eine Access-Datenbank als Datenquelle f&uuml;r unsere Beispiele nutzen, hei&szlig;t die entsprechende Klasse also <b>OLEDBConnectionStringBuilder<\/b>. Die folgende Prozedur erstellt ein neues Objekt auf Basis dieser Klasse und speichert es in der Variablen <b>ConnectionStringBuilder<\/b>. Die Objektvariable stellt alle f&uuml;r die aktuelle Verbindung m&ouml;glichen Parameter als Eigenschaften zur Verf&uuml;gung, sodass Sie die gew&uuml;nschten Elemente einfach per IntelliSense ausw&auml;hlen wollen.<\/p>\n<p>Im vorliegenden Fall weisen wir so den Parameter <b>DataSource <\/b>und den Parameter <b>Provider <\/b>zum Objekt <b>ConnectionStringBuilder <\/b>hinzu und stellen so die Verbindungszeichenfolge zusammen, die wir dann &uuml;ber die Eigenschaft <b>ConnectionString <\/b>abfragen und beim Erstellen des <b>OLEDBConnection<\/b>-Objekts verwenden k&ouml;nnen:<\/p>\n<pre>public static void ConnectionstringBuilder() {\r\n     OleDbConnectionStringBuilder ConnectionStringBuilder = \r\n         new OleDbConnectionStringBuilder();\r\n     ConnectionStringBuilder.DataSource = \"Suedsturm.mdb\";\r\n     ConnectionStringBuilder.Provider = \r\n         \"Microsoft.Jet.OLEDB.4.0\";\r\n     OleDbConnection cnn = new OleDbConnection(\r\n         ConnectionStringBuilder.ConnectionString);\r\n     try {\r\n         cnn.Open();\r\n         Console.WriteLine(\"Provider: {0}\", cnn.Provider);\r\n         Console.WriteLine(\"DataSource: {0}\", \r\n             cnn.DataSource);\r\n         Console.ReadLine();\r\n         cnn.Close();\r\n     }\r\n     catch(Exception e) {\r\n         Console.WriteLine(\"Fehler: {0}\", e.Message);\r\n         Console.ReadLine();\r\n     }\r\n}<\/pre>\n<p>Im Folgenden haben wir die Ausgabe einiger Eigenschaften des <b>Connection<\/b>-Objekts in eine rudiment&auml;re Fehlerbehandlung gesteckt. Diese greift, wenn innerhalb des <b>try<\/b>-Blocks ein Fehler auftritt. Dann wird der <b>catch<\/b>-Block ausgel&ouml;st, der eine Fehlermeldung in der Konsole ausgibt. Mehr zum Thema Fehlerbehandlung lesen Sie im Artikel <b>Fehlerbehandlung mit C#<\/b>.<\/p>\n<h2>Verbindungszeichenfolge speichern<\/h2>\n<p>Wenn Sie unter Access eine Backend-Datenbank verwenden, wird der Pfad zu den verkn&uuml;pften Tabellen in der Systemtabelle <b>MSysObjects <\/b>gespeichert. Sollten die verkn&uuml;pften Tabellen nicht an der vorgesehen Stelle verf&uuml;gbar sein, l&ouml;st dies einen Fehler aus. Dies f&auml;ngt man unter Access ab, indem man beim &Ouml;ffnen der Datenbank pr&uuml;ft, ob die verkn&uuml;pfte Datenbank sich am vorgesehenen Ort befindet. Falls nicht, blendet man einen Dialog ein, der dem Benutzer die Auswahl des neuen Speicherorts der Backend-Datenbank erm&ouml;glicht und verkn&uuml;pft die Tabellen dann erneut.<\/p>\n<p>Dieses Verhalten wollen wir unter C# f&uuml;r Desktop-Anwendungen &auml;hnlich abbilden &#8211; zumindest so, dass es f&uuml;r den Benutzer so aussieht. Intern l&auml;uft es nat&uuml;rlich etwas anders: Es gibt ja keine Verkn&uuml;pfung zu einer Datenbank, sondern wir verwenden eine Zeichenkette, welche den Speicherort der zu nutzenden Datenbank angibt. Zumindest in den bisherigen Beispielen (und der Einfachheit halber auch in den meisten weiteren) legen wir die Datenbank direkt im Verzeichnis der <b>.exe<\/b>-Datei ab. Sp&auml;testens, wenn Sie einmal eine Anwendung f&uuml;r den Mehrbenutzerbetrieb auslegen und dabei eine Datei wie eine Access-Datenbank, aber m&ouml;glicherweise auch eine Excel- oder XML-Datei als Datenquelle nutzen, sollten Sie eine M&ouml;glichkeit vorsehen, das Vorhandensein der Quelldatei zu pr&uuml;fen und gegebenenfalls den Speicherort der Datei neu zu ermitteln.<\/p>\n<p>Hierzu besteht die erste Aufgabe darin, den Pfad zur Quelldatei an einem Ort zu speichern, der au&szlig;erhalb der kompilierten Anwendung liegt. Anderenfalls m&uuml;ssten Sie die Anwendung ja jedes Mal neu kompilieren, wenn sich der Pfad &auml;ndert. Das k&ouml;nnen Sie bei selbst genutzten Anwendungen tun, aber sicher nicht bei solchen Anwendungen, die Sie an Kunden oder andere Benutzer weitergeben.<\/p>\n<p>Unter Access h&auml;tten wir f&uuml;r einen solchen Zweck einfach eine lokale Optionentabelle verwendet oder alternativ eine Textdatei. Eine C#-Desktop-Anwendung jedoch enth&auml;lt ja keine eigenen Tabellen zum Speichern von Daten, also m&uuml;ssen wir schon auf eine Art Konfigurationsdatei zur&uuml;ckgreifen. Es gibt jedoch gute Nachrichten: C# sieht f&uuml;r Desktop-Anwendungen eine M&ouml;glichkeit vor, Konfigurationsdateien zu pflegen und die enthaltenen Daten einfach per Code einzulesen und auch zu &auml;ndern.<\/p>\n<p>Wie Sie die Verbindungszeichenfolge in einer Konfigurationsdatei speichern, erfahren Sie im Artikel <b>Anwendungskonfigurationsdateien<\/b>.<\/p>\n<h2>Der DataAdapter<\/h2>\n<p>Genau wie die &uuml;brigen ADO.NET-Objekte gibt es auch den <b>DataAdapter <\/b>wieder in verschiedenen Klassen. Dementsprechend hei&szlig;t der <b>DataAdapter <\/b>beispielsweise <b>SqlDataAdapter<\/b>, <b>OdbcDataAdapter <\/b>oder <b>OleDbDataAdapter<\/b> &#8211; je nachdem, mit welcher Klasse Sie auf welchen Datenbanktyp zugreifen m&ouml;chten.<\/p>\n<p>Wir besch&auml;ftigen uns der Einfachheit halber immer noch mit unserer Access-Beispieldatenbank <b>Suedsturm.mdb<\/b>, also nutzen wir den <b>OleDbDataAdapter<\/b>. Im Folgenden reden wir jedoch neutral von <b>DataAdapter<\/b>, nur im Beispielcode finden Sie entsprechend die Objektbezeichnung <b>OleDbDataAdapter<\/b>.<\/p>\n<p>Was bietet uns der <b>DataAdapter<\/b> Mit dem <b>Command<\/b>&#8211; und dem <b>DataReader<\/b>-Objekt konnten wir ja immerhin schon einmal Auswahlabfragen ausf&uuml;hren und die Ergebnisse vorw&auml;rts durchlaufen oder Aktionsabfragen ansto&szlig;en. Der <b>DataReader <\/b>erlaubt es aber beispielsweise nicht, einen der enthaltenen Datens&auml;tze zu &auml;ndern und die ge&auml;nderte Version zur&uuml;ck in die zugrunde liegenden Tabellen zu schreiben. Genauso wenig, wie Sie damit durch die Datens&auml;tze navigieren k&ouml;nnen &#8211; es geht nur vorw&auml;rts.<\/p>\n<p>Au&szlig;erdem sind <b>Command <\/b>und <b>DataReader <\/b>Objekte, die eine Verbindung zur Datenbank ben&ouml;tigen. Gerade dies ist nat&uuml;rlich f&uuml;r Web-Anwendungen oder Anwendungen auf mobilen Endger&auml;ten nicht sinnvoll, und auch f&uuml;r Desktop-Anwendungen in Mehrbenutzerumgebungen k&ouml;nnen nicht endlos viele Verbindungen gleichzeitig offen gehalten werden. Daher sieht ADO.NET einige Objekte vor, mit denen Sie die Daten aus der Datenbank einlesen, bearbeiten und wieder zur&uuml;ckschreiben k&ouml;nnen. Dabei ist nur f&uuml;r das Einlesen und das Zur&uuml;ckschreiben eine Verbindung n&ouml;tig, zwischendurch wird die Verbindung getrennt.<\/p>\n<p>Und hier kommt der <b>DataAdapter <\/b>ins Spiel (je nach Anwendungsfall als <b>SqlDataAdapter<\/b>, <b>OdbcDataAdapter<\/b>, <b>OleDbDataAdapter <\/b>et cetera): Er stellt die Verbindung zwischen Client und Server her, um die ben&ouml;tigten Daten aus den Tabellen der Datenbank in lokale Objekte zu &uuml;bertragen und diese nach &Auml;nderungen wieder zur&uuml;ckzuschicken. Dabei stellt der <b>DataAdapter <\/b>nur Verbindungen zum Server her, wenn tats&auml;chlich Daten bewegt werden m&uuml;ssen.<\/p>\n<h2>Connection- und Command-Objekte<\/h2>\n<p>Die beiden Objekte <b>Connection <\/b>und <b>Command<\/b>, die Sie bereits kennen gelernt haben, d&uuml;rfen Sie jedoch nicht aus Ihrem Ged&auml;chtnis streichen: Das <b>Connection<\/b>-Objekte ben&ouml;tigen wir n&auml;mlich nach wie vor, auch um die Verbindungen des <b>DataAdapters <\/b>herzustellen.<\/p>\n<p>Und das <b>Command<\/b>-Objekt ist immer noch gefragt, wenn es darum geht, &Auml;nderungen an den Daten einer Tabelle vorzunehmen, f&uuml;r die wir die vorhandenen Daten nicht erst einlesen und analysieren m&uuml;ssen. Eine Aktionsabfrage etwa zum Anf&uuml;gen eines neuen Datensatzes oder zum L&ouml;schen oder Bearbeiten vorhandener Datens&auml;tze ist per <b>Command<\/b>-Objekt immer noch schneller, als wenn Sie die entsprechenden Tabellen &uuml;ber den <b>DataAdapter <\/b>in weitere Objekte laden, die Daten dort &auml;ndern und die &Auml;nderungen dann zur&uuml;ckschreiben.<\/p>\n<h2>DataTable und DataRow<\/h2>\n<p>Um mit den &uuml;ber den <b>DataAdapter <\/b>gewonnenen Daten zu arbeiten und etwa in einer Schleife alle Datens&auml;tze zu durchlaufen und anzuzeigen, ben&ouml;tigen Sie noch entsprechende Objekte, um diese zu speichern. Das <b>DataTable<\/b>-Objekt nimmt dabei das Ergebnis einer Tabelle oder Abfrage auf. Seine <b>Rows<\/b>-Eigenschaft erlaubt den Zugriff auf die einzelnen Datens&auml;tze. Diese k&ouml;nnen Sie wiederum mit dem <b>DataRow<\/b>-Objekt referenzieren, um gezielt auf die Inhalte zuzugreifen.<\/p>\n<p>Im Gegensatz zu den Objekten <b>Connection<\/b>, <b>Command <\/b>und <b>DataReader<\/b>, die ja je nach Anforderung etwa aus einem der Namespaces <b>System.Data.Sql<\/b>, <b>System.Data.Odbc <\/b>oder <b>System.Data.OleDb <\/b>stammen, kommen die beiden Objekte <b>DataTable <\/b>und <b>DataRow <\/b>aus dem Namespace <b>System.Data<\/b>. Diesen f&uuml;gen Sie also noch &uuml;ber folgende Anweisung zur Klasse hinzu:<\/p>\n<pre>using System.Data;<\/pre>\n<h2>DataTable f&uuml;llen und durchlaufen<\/h2>\n<p>Damit kommen wir nun endlich zum ersten handfesten Beispiel dieses Artikels. Dabei wollen wir ein <b>DataTable<\/b>-Objekt &uuml;ber einen <b>DataAdapter <\/b>mit den Daten einer Tabelle f&uuml;llen und die Datens&auml;tze durchlaufen und in der Konsole ausgeben (siehe Listing 1).<\/p>\n<pre>public static void DataTableFuellen() {\r\n     string strConnection = \"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Suedsturm.mdb\";\r\n     string strSQL = \"SELECT * FROM tblKategorien\";\r\n     OleDbConnection cnn = new OleDbConnection(strConnection);\r\n     OleDbDataAdapter da = new OleDbDataAdapter(strSQL, cnn);\r\n     DataTable dt = new DataTable();\r\n     da.Fill(dt);\r\n     for (int i = 0; i &lt; dt.Rows.Count; i++) {\r\n         DataRow row = dt.Rows[i];\r\n         Console.WriteLine(\"{0} {1}\", row[0], row);\r\n     }\r\n     Console.ReadLine();\r\n}<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: F&uuml;llen und Durchlaufen einer Tabelle per DataTable<\/span><\/b><\/p>\n<p>Die Methode speichert zun&auml;chst die Verbindungszeichenfolge und die SQL-Abfrage in den beiden Variablen <b>strConnection <\/b>und <b>strSQL<\/b>.<\/p>\n<p>Dann erzeugt sie ein neues Objekt des Typs <b>OleDbConnection <\/b>und &uuml;bergibt dabei gleich die zu verwendende Verbindungszeichenfolge, mit der in diesem Beispiel auf die Access-Datenbank <b>Suedsturm.mdb <\/b>im Verzeichnis der C#-Anwendung selbst zugegriffen werden soll.<\/p>\n<p>Den <b>OleDbDataAdapter <\/b>speichert die Methode nach dem Erstellen und der &Uuml;bergabe der SQL-Anweisung mit <b>strSQL <\/b>und dem <b>Connection<\/b>-Objekt in der Variablen <b>da<\/b>.<\/p>\n<pre>Hier f&auml;llt auf, dass die Methode die Verbindung nicht explizit &ouml;ffnet, indem Sie die &lt;b&gt;Open&lt;\/b&gt;-Methode aufruft. Dies ist nicht n&ouml;tig, da die &lt;b&gt;Fill&lt;\/b&gt;-Methode des &lt;b&gt;DataAdapter&lt;\/b&gt;-Objekts diese Aufgabe f&uuml;r uns &uuml;bernimmt. Sollten Sie f&uuml;r andere Aktionen in diesem Zusammenhang eine offene Verbindung ben&ouml;tigen, k&ouml;nnen Sie diese mit &lt;b&gt;Open &lt;\/b&gt;&ouml;ffnen, m&uuml;ssen dann aber auch mit &lt;b&gt;Close &lt;\/b&gt;f&uuml;r das Schlie&szlig;en der Verbindung sorgen.<\/pre>\n<p>Das <b>DataTable<\/b>-Objekt erzeugt die Methode zun&auml;chst einfach nur und speichert es in der Variablen <b>dt<\/b>. Das F&uuml;llen dieses Objekts erfolgt nicht &uuml;ber eine Methode des Objekts selbst, sondern das Objekt wird als Parameter der <b>Fill<\/b>-Methode des <b>DataAdapter<\/b>-Objekts &uuml;bergeben:<\/p>\n<pre>da.Fill(dt);<\/pre>\n<p>Nun enth&auml;lt das <b>DataTable<\/b>-Objekt bereits alle Datens&auml;tze mit allen Feldern der Tabelle <b>tblKategorien<\/b>. Diese durchl&auml;uft die Methode in einer <b>for<\/b>-Schleife mit der Laufvariablen <b>i<\/b>, welche die Werte von <b>0 <\/b>bis zur Anzahl der Datens&auml;tze minus eins durchl&auml;uft. Die Anzahl der Datens&auml;tze ermitteln wir hier mit dem Ausdruck <b>dt.Rows.Count<\/b>. <b>Rows <\/b>ist die Auflistung aller Datens&auml;tze.<\/p>\n<p>&Uuml;ber diese Auflistung erhalten wir mit dem entsprechenden Indexwert ein <b>DataRow<\/b>-Objekt, das wir mit jedem Schleifendurchlauf neu mit der Variablen <b>row <\/b>referenzieren:<\/p>\n<pre>DataRow row = dt.Rows[i];<\/pre>\n<p>&Uuml;ber den Index der Felder gibt die Methode nun die Inhalte der ersten beiden Felder in der Konsole aus:<\/p>\n<pre>Console.WriteLine(\"{0} {1}\", row[0], row);<\/pre>\n<p>In dieser Anweisung k&ouml;nnten wir auch konkret auf die Feldnamen zugreifen:<\/p>\n<pre>Console.WriteLine(\"{0} {1}\", row[\"KategorieID\"], row[\"Kategoriename\"]);<\/pre>\n<p>Anschlie&szlig;end gibt die Methode die Liste der Kategorien aus der Tabelle <b>tblKategorien <\/b>in der Konsole aus (siehe Bild 1).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_01\/pic_24_002.png\" alt=\"Ausgabe der Daten der Tabelle tblKategorien\" width=\"425\" height=\"164,3333\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Ausgabe der Daten der Tabelle tblKategorien<\/span><\/b><\/p>\n<p>Wir haben nun das <b>OleDbConnection<\/b>-Objekt und die SQL-Anweisung per Konstruktor an das <b>OleDbDataAdapter<\/b>-Objekt &uuml;bergeben. Sie k&ouml;nnen auch zun&auml;chst ein <b>OleDbCommand<\/b>-Objekt erstellen und dieses dann als Konstruktor beim Erstellen des <b>OleDbDataAdapter<\/b>-Objekts &uuml;bergeben:<\/p>\n<pre>string strConnection = \"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Suedsturm.mdb\";\r\nstring strSQL = \"SELECT * FROM tblKategorien\";\r\nOleDbConnection cnn = new OleDbConnection(strConnection);\r\nOleDbCommand cmd = new OleDbCommand(strSQL, cnn);\r\nOleDbDataAdapter da = new OleDbDataAdapter(cmd);<\/pre>\n<p>Oder Sie verwenden beim Erstellen des <b>DataAdapter<\/b>-Objekts die konstruktorlose Variante und weisen das <b>OleDbCommand<\/b>-Objekt erst im Anschluss &uuml;ber die Eigenschaft <b>SelectCommand <\/b>hinzu:<\/p>\n<pre>...\r\nOleDbCommand cmd = new OleDbCommand(strSQL, cnn);\r\nOleDbDataAdapter da = new OleDbDataAdapter();\r\nda.SelectCommand = cmd;<\/pre>\n<p>Warum ist hier von <b>SelectCommand <\/b>die Rede, und nicht einfach von <b>Command<\/b> Weil der <b>DataAdapter <\/b>ja zun&auml;chst einmal Daten liefern soll. Daher soll das <b>Command<\/b>-Objekt eine <b>Select<\/b>-Anweisung enthalten und nicht etwa eine Aktionsabfrage.<\/p>\n<h2>Anzahl der Datens&auml;tze per Fill<\/h2>\n<p>Wenn Sie ein <b>DataTable<\/b>-Objekt mit der <b>Fill<\/b>-Methode des <b>DataAdapter<\/b>-Objekts f&uuml;llen, liefert die <b>Fill<\/b>-Methode einen R&uuml;ckgabewert, den Sie hier direkt nutzen k&ouml;nnen: Es handelt sich n&auml;mlich um die Anzahl der zur&uuml;ckgelieferten Datens&auml;tze. Im folgenden Ausschnitt der Methode <b>DataTableFuellenIV <\/b>schreiben wir das Ergebnis der <b>Fill<\/b>-Methode in die Variable <b>anzahl<\/b>, die wir dann als Vergleichswert des zweiten Parameters der <b>for<\/b>-Schleife nutzen:<\/p>\n<pre>...\r\nDataTable dt = new DataTable();\r\nint anzahl = da.Fill(dt);\r\nfor (int i = 0; i &lt; anzahl; i++)\r\n{\r\n     DataRow row = dt.Rows[i];\r\n     Console.WriteLine(\"{0} {1}\", row[0], row);\r\n}\r\n...<\/pre>\n<h2>DataTable per foreach durchlaufen<\/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\/55000024\/\">\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\/55000024?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\/55000024\/\"\/>\n\t\t\t\t\t\t\t\t<input type=\"hidden\" name=\"rcp_login_nonce\" value=\"9231c3f2cb\"\/>\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>Im ersten Teil unserer Artikelreihe zum Thema ADO.NET haben wir uns angesehen, wie Sie mit dem DataReader-Objekt auf die Daten einer Tabelle zugreifen und wie Sie mit dem Command-Objekt Aktionsabfragen durchf&uuml;hren k&ouml;nnen. Im vorliegenden Teil sehen wir uns an, wie Sie mit dem DataAdapter-Objekt auf die Daten einer Datenbank zugreifen und das DataSet- und das DataTable-Objekt einsetzen, um verbindungslos mit den Daten einer Datenbank zu arbeiten.<\/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":[66012016,662016,44000008,44000023],"tags":[],"yst_prominent_words":[66062051,66062047,66062059,66062061],"class_list":["post-55000024","post","type-post","status-publish","format-standard","hentry","category-66012016","category-662016","category-Datenzugriffstechnik","category-PowerApps"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000024","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=55000024"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000024\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000024"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000024"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000024"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000024"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}