Anbei zwei kleine Projekte, sehr ähnlich den Samples zu Daten laden und speichern.
Hauptunterschied ist, dass hier die Datasets in Datenbanken geschrieben werden. Dabei wird der Connector benutzt, ein Assistent, der zB automatisch anspringt, wenn man eine Datenbank-Datei dem Projekt hinzufügt. Der Connector analysiert dann die Datenbank, und erstellt ein dazu kompatibles typisiertes Dataset, und erstellt für jede Tabelle auch einen typisierten TableAdapter, mit dem die Tabelle persistiert werden kann.
BilderSerie, wie das vonstatten geht:
Zunächst ist in Form_Load per
Weil Primkeys konfiguriert man mit AutoIncrement, also die Db legt den PK endgültig fest, nachdem ja bereits im Dataset für neue Datensätze ein provisorischer PK generiert werden musste (Pficht-Feld).
Sieht man ja auch inne
Also im Normalfall (Datensatz mit Autowert-PK) ist das Inserten immer ein bidirektionaler Vorgang: Das Dataset sendet den Datensatz an die Db, bekommt von der Db den endgültigen Primkey dieses Datensatzes zurück und muss ihn einpflegen.
Ansonsten ist Laden (
Weitere Select-Queries kann man den TableAdaptern per Kontext-Menu im Dataset-Designer hinzufügen - vorzugsweise um anhand von Parametern eine gefilterte Untermenge der Db-Tabelle abzurufen.
Hauptunterschied ist, dass hier die Datasets in Datenbanken geschrieben werden. Dabei wird der Connector benutzt, ein Assistent, der zB automatisch anspringt, wenn man eine Datenbank-Datei dem Projekt hinzufügt. Der Connector analysiert dann die Datenbank, und erstellt ein dazu kompatibles typisiertes Dataset, und erstellt für jede Tabelle auch einen typisierten TableAdapter, mit dem die Tabelle persistiert werden kann.
BilderSerie, wie das vonstatten geht:
- zunächst die mdb ins Ausführungsverzeichnis kopieren, und im Projektmappenexplorer die Ansicht "alle Dateien" aktivieren, damit man die mdb auch sieht, obwohl sie noch nicht zum Projekt gehört
- Dann natürlich die mdb dem Projekt hinzufügen, was den Connector-Assistenten startet
- "Dataset"-Weiter klicksen, und alle Tabellen auswählen
"Finish" klicksen - Hier sieht man über der mdb nun das neu generierte typisierte Dataset mit 3 untergeordneten Dateien, also es besteht derzeit aus 4 Dateien: .xsd, .Designer.vb, .xsc, .xss
Es empfiehlt sich, die .xsd ins projektverzeichnis zu verschieben, denn im Debug-Ordner haben eingebundene Projekt-Dateien eigentlich nichts verloren. Dass die .mdb dort verbleiben darf ist eine Ausnahme, geschuldet ihrer besonderen Konfiguration - ich komme noch dazu. - Doppelklick auf die .xsd öffnet den Dataset-Designer:
Dataset1 hat nur eine Tabelle, aber beachte, dass unten dran derDatatabel1TableAdapter
dran hängt, ein typisierter Adapter zwischen DataTable1 und der Datenbank - Im ProjektmappenExplorer die .mdb anwählen und F4 drücken, um zu den Datei-Eigenschaften zu kommen. Dort die Property "copy to output-Directory - do-not-copy" einstellen, weil sonst werden Daten-Änderungen bei jedem Testlauf überschrieben, und man hat den (falschen) Eindruck, nix würde funktionieren.
- Und in den Settings der ConnectionString ist falsch:
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\bin\Debug\MostSimple.mdb;Persist Security Info=True
steht da, aber das|DataDirectory|
ist bereits\bin\Debug
- also der Connectionstring muss aufProvider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|MostSimple.mdb;Persist Security Info=True
korrigiert werden, sonst gibts komische Fehler, weil er die Datei nicht findet.
(naja, vlt. einfacher wäre gewesen, die .mdb eben nicht im Debug-Ordner einzubinden, sondern auf Projektebene, und ihre Datei-Eigenschaft halt auf "Copy if newer" zu setzen statt auf "not copy") - Uff! - nun können wir endlich den Form-Designer öffnen, und vom Datenfenster (vs2010: "Menu - Data - Show-Data-Sources" / vs2013: "Menu - View - Other-Windows - Data-Sources") die Tabelle aufs Form ziehen, wodurch das DataGridView generiert wird, sowie eine typDataset-Instanz, eine TableAdapter-Instanz, und eine BindingSource.
. . .
Darüber hinaus wird auch ein TableAdapterManager und ein BindingNavigator hingeneriert, aber diese beiden Dinge sind unnützer Schrott, und sofort wieder runterzuwerfen.
VB.NET-Quellcode
- Private _IdentityCommand As New OleDb.OleDbCommand("SELECT @@IDENTITY")
- Private Sub frmMostSimple_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
- AddHandler DataTable1TableAdapter.Adapter.RowUpdated, AddressOf RequeryId
- Reload()
- End Sub
- Private Sub RequeryId(ByVal sender As Object, ByVal e As System.Data.OleDb.OleDbRowUpdatedEventArgs)
- If e.StatementType = StatementType.Insert Then
- _IdentityCommand.Connection = e.Command.Connection
- _IdentityCommand.Transaction = e.Command.Transaction
- e.Row(e.Row.Table.PrimaryKey(0)) = _IdentityCommand.ExecuteScalar()
- End If
- End Sub
- Private Sub Reload()
- DataTable1TableAdapter.Fill(DataSet1.DataTable1)
- End Sub
- Private Sub Save()
- 'Me.Validate: in Bearbeitung stehende Zellwerte - falls valide - als Eingabe übernehmen
- If Not Me.Validate Then Media.SystemSounds.Hand.Play() : Return
- DataTable1TableAdapter.Update(DataSet1.DataTable1)
- Media.SystemSounds.Asterisk.Play()
- End Sub
AddHandler
(zeile#4) das TableAdapter_RowUpdated
-Event auf die RequeryId()
-Event-Methode zu leiten, damit bei jedem ausgeführten Insert-Command ein Select-Command nachgeschossen wird, welches den Primkey abfragt, der von der DB vergeben wurde.Weil Primkeys konfiguriert man mit AutoIncrement, also die Db legt den PK endgültig fest, nachdem ja bereits im Dataset für neue Datensätze ein provisorischer PK generiert werden musste (Pficht-Feld).
Sieht man ja auch inne
RequeryId()
-Methode: der Db-Primkey-Wert wird explizit als Primkey im typDataset eingetragen (zeile#12).Also im Normalfall (Datensatz mit Autowert-PK) ist das Inserten immer ein bidirektionaler Vorgang: Das Dataset sendet den Datensatz an die Db, bekommt von der Db den endgültigen Primkey dieses Datensatzes zurück und muss ihn einpflegen.
Ansonsten ist Laden (
Reload()
) und Speichern (Save()
) bei diesem Simpel-Dataset höchst-simpel: die Kommunikation übernimmt der TableAdapter mit seinen eingebauten generierten Select, Delete, Update, Insert
- Commands. Wir selbst haben mit Sql, Db-Commads, -Readern und Kram nichts zu schaffen. Weitere Select-Queries kann man den TableAdaptern per Kontext-Menu im Dataset-Designer hinzufügen - vorzugsweise um anhand von Parametern eine gefilterte Untermenge der Db-Tabelle abzurufen.
Dieser Beitrag wurde bereits 9 mal editiert, zuletzt von „ErfinderDesRades“ ()