|
Zugriff auf Access-Datenbanken mit ADO.NET
|
 |
|
Autor/Einsender: |
|
Michael Werner |
|
|
|
Ziel dieses kleinen Tutorials ist es, einen Datenbankzugriff auf eine Access-Datenbank
für Einsteiger in Visual Basic .Net darzustellen.
|
|
|
Das Beispiel ist absichtlich sehr einfach
gehalten und bietet eine der einfachen Möglichkeiten des Datenbankzugriffs über den
CommandBuilder. (siehe Hinweis zu
den Einschränkungen beim Einsatz des CommandBuilders)
|
|
1. Access-Datenbank anlegen |
|
Zunächst muss eine Datenbank angelegt werden. Dazu nutzen wir Microsoft
Access 2000 und verwenden entweder, wie abgebildet den Assistenten und
der Auswahl Leere Access-Datenbank, oder das Menü über Datei
-> Neu -> Datenbank.
|
|
Übergangsweise können wir die neuangelegte Datenbank in einem
beliebigen Verzeichnis speichern. In unserem Beispiel erhält die Datenbank
den Namen UserDB.mdb.
Der Tabelle geben wir den Namen Users.
|
|
Ist später unser Projekt angelegt,
verschieben wir die Datenbank in das BIN-Verzeichnis des Projektes. Dort
kann sie dann mittels Application.StartupPath gefunden
werden.
|
|
Als Nächstes erstellen wir eine Tabelle in der Entwurfsansicht:
|
Feldname |
Felddatentyp |
ID |
Autowert |
Username |
Text |
Passwort |
Text |
Email |
Text |
Datum |
Text |
|
Das Tabellenfeld ID soll unser Primärschlüssel werden. Dazu einfach
das Feld ID markieren -> Rechte Maustaste -> Primärschlüssel.
Wurde dieser Schritt korrekt durchgeführt, ist dies durch einen
kleinen Schlüssel vor dem Feld ID sichtbar.
|
Um doppelte Einträge zu vermeiden, werden die Felder Username, Passwort und Email indiziert, das heißt, es werden
keine doppelten Einträge in der Datenbank zugelassen. Außerdem wird
dadurch eine Eingabe erforderlich gemacht. Für diesen Schritt wird
lediglich jeweils das entsprechende Feld markiert und unter dem Punkt
|
Eingabe erforderlich: Ja
Indiziert : Ja (ohne Duplikate)
|
eingestellt. Beachten Sie beim Testen des Projekts, dass durch diese gemachten Einstellungen die Felder Username, Passwort und Email
eine Eingabe erfordern und weder Leerzeile noch doppelte Einträge erlauben.
Andernfalls erhalten Sie eine Fehlermeldung.
|
Um in unserem Projekt dann auch das erste AHA-Erlebnis zu haben,
erstellen wir nun noch in Access einen Beispiel-Datensatz in der
Datenblattansicht (im Menü -> Ansicht -> Datenblattansicht).
Jetzt wird nur noch gespeichert, und Access kann geschlossen werden.
|
|
2. Neues Projekt in Visual Basic .Net anlegen |
|
Ist VB.Net gestartet, vergeben wir einen beliebigen Projektnamen. und
bevor wir anfangen, schreiben wir ganz oben als erste Code-Zeile im neuen Projekt den Verweis (Import) auf OleDB (Access):
|
|
|
Imports System.Data.OleDB
|
|
|
Jetzt benötigen wir die folgenden Steuerelemente, die wir allesamt
aus der Werkzeugleiste (ToolBox) entnehmen können, und die auf der Form1
entsprechend angeordnet werden:
|
Objekt |
Name im Projekt |
DataGrid |
DataGrid1 |
ComboBox |
cboUsername |
TextBox |
txtPasswort |
TextBox |
txtEmail |
Button |
btnInsert |
Button |
btnDelete |
Button |
btnUpdate |
Button |
btnExit |
|
|
3. Verbindung zur Datenbank herstellen und Tabelle anzeigen |
|
Als nächstes benötigen wir die Anbindung an die eben erstellte
Access-Datenbank, indem die Connection definiert, der SELECT-String bestimmt, beides zu einem Command
zusammengestellt und der Adapter für den Command deklariert wird.
|
Das DataSet wird erst in der Prozedur LOAD_Table gefüllt und im DataGrid angezeigt.
|
|
|
Private dbpath As String = _
System.IO.Path.Combine(Application.StartupPath, "UserDB.mdb")
Private conn As New OleDbConnection(_
"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & dbpath & ";")
Private sql As String = "SELECT * FROM Users;"
Private cmd As New OleDbCommand(sql, conn)
Private da As New OleDbDataAdapter(cmd)
Private ds As New DataSet
|
|
|
In einer Prozedur wollen wir nun die Verbindung herstellen, das DataSet füllen und
die Tabelle im DataGrid anzeigen. Dazu muss die Connection zunächst geöffnet werden,
das DataSet zunächst gelöscht und dann mit Fill neu gefüllt werden.
|
Die Anzeige der Tabelle im DataGrid wird mit SetDataBinding vollzogen und anschließend
wird die Verbindung zur Datenbank wieder geschlossen.
|
|
|
Private Sub LOAD_Table()
Try
'Verbindung zur Datenbank öffnen
conn.Open()
'Inhalte des Dataset zunächst löschen
ds.Clear()
'Dataset mit der Tabelle Users füllen
da.Fill(ds, "Users")
'Datagrid anbinden
DataGrid1.SetDataBinding(ds, "Users")
'Combobox anbinden
cboUsername.DataSource = ds
cboUsername.DisplayMember = "Users.Username"
Catch ex As OleDbException
MessageBox.Show(ex.Message, "Fehler", MessageBoxButtons.OK, _
MessageBoxIcon.Exclamation)
Finally
'Verbindung zur Datenbank auf jeden Fall wieder schließen
conn.Close()
End Try
End Sub
|
|
|
Jetzt kann das Projekt erstellt werden (Menü: Projekt erstellen).
Bei einer Ausführung des Projekts zu diesem Zeitpunkt (F5 bzw.
Starten), kommt es ggfls. zu der oben genannten Fehlermeldung, da die Datenbank nicht gefunden werden kann.
Deshalb ist es wichtig, dass die Datenbank in das Bin-Verzeichnis des
Projektes kopiert oder verschoben wird.
|
Ist dies erfolgt, müsste beim Ausführen des Projekts die Tabelle mit dem Beispieldatensatz angezeigt werden.
|
|
4. Datensätze hinzufügen, löschen und ändern |
|
Nun kommen die drei Prozeduren, um Datensätze hinzuzufügen, zu löschen und zu
ändern, denen die Werte aus der ComboBox und den TextBoxen
übergeben werden:
|
|
|
INSERT_DataRow(cboUsername.Text, txtPasswort.Text, txtEmail.Text)
DELETE_DataRow(cboUsername.Text)
UPDATE_DataRow(cboUsername.Text)
|
|
|
Das DataGrid dient in diesem Falle nur als Anzeige der
Tabelleninhalte. Ein Möglichkeit zur Änderung direkt im DataGrid wurde durch Einstellung ReadOnly = true ausgeschlossen.
|
Um Veränderungen an DataSet / Tabelle / Datenbank vorzunehmen, gibt es grundsätzlich
verschiedene Möglichkeiten. Um diese Demonstration möglichst einfach zu halten, wurde
mit dem CommandBuilder nur einer dieser Wege ausgewählt.
|
Kurz etwas über den asynchronen Datenzugriff in ADO.NET
|
Der DataAdapter stellt die Verbindung zwischen DataSet und Datenbank her.
Das DataSet ist ein im Speicher abgelegtes Abbild der Datenbank. Die Verbindung zur Datenbank wird nach dem Auslesen in das DataSet
getrennt.
|
Änderungen werden zunächst nur im DataSet (Arbeitsspeicher) vorgenommen.
Sind diese vollständig, wird die Verbindung zur Datenbank noch
einmal kurzzeitig hergestellt, um die neuen Daten in die Datenbank zu schreiben (Update-Methode).
|
Was macht der CommandBuilder?
|
Das CommandBuilder-Objekt wird mit dem DataAdapter verkoppelt, dadurch werden Änderungen im DataSet automatisch mit der DB abgeglichen, ohne dass
extra ein SQL-Befehl geschrieben werden muss. Es genügt ein DataAdapter.Update, um die Datenänderung
in der Datenbank festzuhalten.
|
Die OleDbDataAdapter.Update-Methode ruft automatisch für jede eingefügte, aktualisierte oder gelöschte Zeile im DataSet die INSERT-, UPDATE- bzw. DELETE-Anweisung auf.
|
Alle drei Prozeduren sind ähnlich aufgebaut. Zunächst wird ein CommandBuilder-Objekt
instanziert,
dann die Verbindung zur Datenbank geöffnet, die DataTable bearbeitet (verändert),
mit DataAdapter.Update in die Datenbank geschrieben, die Connection wieder geschlossen
und die geänderte Tabelle wieder neu angezeigt.
|
|
|
|
Private Sub INSERT_Datarow(ByVal strUser As String, ByVal strPw _
As String, ByVal strEmail As String)
Dim cb As OleDbCommandBuilder = New OleDbCommandBuilder(da)
Try
conn.Open()
'Im DataSet einen neuen Datensatz hinzufügen
'Der Tabelle eine neue DataRow hinzufügen
Dim row As DataRow = ds.Tables("Users").NewRow
'Werte übergeben
row("Username") = strUser
row("Passwort") = strPw
row("Email") = strEmail
row("Datum") = DateTime.Now.ToShortDateString
ds.Tables("Users").Rows.Add(row)
'Datenbank updaten
da.Update(ds, "Users")
MessageBox.Show("Neuer Datensatz Username " & strUser & _
" hinzugefügt!", "Neuer Datensatz", MessageBoxButtons.OK, _
MessageBoxIcon.Information)
Catch ex As OleDbException
MessageBox.Show(ex.Message, "Fehler", MessageBoxButtons.OK, _
MessageBoxIcon.Exclamation)
Finally
conn.Close()
End Try
LOAD_Table()
End Sub
|
|
|
|
|
Private Sub DELETE_Datarow(ByVal strUser As String)
Dim cb As OleDbCommandBuilder = New OleDbCommandBuilder(da)
If MessageBox.Show("Soll der Datensatz Username " & strUser & _
" wirklich gelöscht werden?", "Löschen?", _
MessageBoxButtons.YesNo, _
MessageBoxIcon.Question) = DialogResult.No Then
Exit Sub
End If
Try
conn.Open()
Dim row As DataRow
Dim i As Integer
Dim dt As DataTable = ds.Tables("Users")
'alle Zeilen des DataTable durchlaufen
For Each row In dt.Rows
If row!Username = strUser Then
row.Delete() 'DataRow löschen
i += 1
End If
Next
'Datenbank updaten
da.Update(ds, "Users")
If i > 0 Then
MessageBox.Show("Datensatz(e) " & strUser & _
" wurde(n) gelöscht!" & vbNewLine & "Anzahl: " & _
CStr(i), "Gelöscht", _
MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show("Kein Datensatz Username " & strUser & _
" vorhanden!", "Nicht vorhanden", _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
Catch ex As OleDbException
MessageBox.Show(ex.Message, "Fehler", MessageBoxButtons.OK, _
MessageBoxIcon.Exclamation)
Finally
conn.Close()
End Try
LOAD_Table()
End Sub
|
|
|
|
|
Private Sub UPDATE_Datarow(ByVal strUser As String)
Dim cb As OleDbCommandBuilder = New OleDbCommandBuilder(da)
If MessageBox.Show("Soll das Passwort / Email im Datensatz " _
& vbNewLine & "Username: " & strUser & vbNewLine _
& "wirklich geändert werden?" & vbNewLine & vbNewLine _
& "Neues Passwort: " & txtPasswort.Text & vbNewLine _
& "Neue Email: " & txtEmail.Text, _
"Passwort und/oder Email ändern?", MessageBoxButtons.YesNo, _
MessageBoxIcon.Question) = DialogResult.No Then
Exit Sub
End If
Try
conn.Open()
Dim row As DataRow
Dim i As Integer
Dim dt As DataTable = ds.Tables("Users")
'alle Zeilen des DataTable durchlaufen
For Each row In dt.Rows
'Werte in der DataRow überschreiben
If row!Username = strUser Then
row!Passwort = txtPasswort.Text
row!Email = txtEmail.Text
row!Datum = DateTime.Now.ToShortDateString
i += 1
End If
Next
'Datenbank updaten
da.Update(ds, "Users")
If i > 0 Then
MessageBox.Show("Datensatz(e) Username " & strUser & _
" wurde(n) geändert!" & vbNewLine & vbNewLine & _
"Geändert: Passwort " & txtPasswort.Text & vbNewLine & _
"Geändert: Email " & txtEmail.Text & vbNewLine & _
"Anzahl: " & CStr(i), "Update", MessageBoxButtons.OK, _
MessageBoxIcon.Information)
Else
MessageBox.Show("Kein Datensatz Username " & strUser & _
" vorhanden!", "Nicht vorhanden", MessageBoxButtons.OK, _
MessageBoxIcon.Exclamation)
End If
Catch ex As OleDbException
MessageBox.Show(ex.Message, "Fehler", MessageBoxButtons.OK, _
MessageBoxIcon.Exclamation)
Finally
conn.Close()
End Try
LOAD_Table()
End Sub
|
|
|
|
Das Beispiel-Projekt demonstriert, wie eine Verbindung zu einer Access-Datenbank hergestellt,
ein Tabelle der Datenbank angezeigt, Datensätze hinzugefügt, geändert oder gelöscht werden können.
|
|
|
|
Das automatische Generierung von Befehlen mit Hilfe des CommandBuilders
unterliegt folgenden Einschränkungen:
|
Ist die DataTable einer einzigen Datenbanktabelle zugeordnet oder aus einer solchen generiert
worden, können mit Hilfe des DbCommandBuilder-Objekts automatisch DeleteCommand, InsertCommand
und UpdateCommand für DbDataAdapter generiert werden.
|
Nur nicht verknüpfte Tabellen:
|
Die Logik für die automatische Generierung von Befehlen generiert
INSERT-, UPDATE- oder DELETE-Befehle für eigenständige Tabellen, wobei Verknüpfungen mit anderen Tabellen in der Datenquelle
unberücksichtigt bleiben.
|
Tabellennamen und Spaltennamen:
|
Die Logik für die automatische Generierung von Befehlen versagt, wenn
Spaltennamen oder Tabellennamen, Sonderzeichen wie Leerzeichen, Punkte,
Fragezeichen oder andere nicht alphanumerische Zeichen enthalten, selbst wenn diese durch Klammern getrennt sind.
|
|
Bei Fragen zu diesem Tutorial nutzen Sie bitte unser VB.Net-Forum. |
|