Hallo,
ich versuche, meinen
DB-Zugriff konsequent über
DbProviderFactory zu programmieren; das klappt jetzt auch:
Code:
using sc = System.Data.Common;
using
fb = FirebirdSql.Data.FirebirdClient;
// Deklaration
private sc.DbProviderFactory dataFactory;
private sc.DbConnection conn;
// DataAdapter und CommandBuilder für jede Tabelle getrennt,
// damit automatisches Update möglich ist
private sc.DbDataAdapter[] da;
private sc.DbCommandBuilder[] cmdb;
// Verbindung zur
DB vorbereiten
dataFactory = sc.DbProviderFactories.GetFactory(s0);
conn = dataFactory.CreateConnection();
da = new sc.DbDataAdapter[Daten.Tables.Count];
cmdb = new sc.DbCommandBuilder[Daten.Tables.Count];
Connection klappt - das ist hier nicht das Thema. Daten ist ein typisiertes, von XSD erzeugtes DataSet.
Nun erzeuge ich die
SelectCommands und hole mir für jede der Tabellen die Daten ins DataSet; auch das klappt (die
Exception steht nur vorsorglich da):
Code:
tbl = Daten.Tables[x1];
// DataAdapter erzeugen
da[x1] = dataFactory.CreateDataAdapter();
// SelectCommand erzeugen und zuordnen
da[x1].SelectCommand = dataFactory.CreateCommand();
da[x1].SelectCommand.Connection = conn;
da[x1].SelectCommand.CommandText = "SELECT * FROM " + tbl.TableName;
// CommandBuilder erzeugen und zuordnen
cmdb[x1] = dataFactory.CreateCommandBuilder();
cmdb[x1].DataAdapter = da[x1];
// jetzt Befehle ausführen
try { da[x1].Fill(Daten, tbl.TableName);
} catch (
Exception e)
{ System.Windows.Forms.MessageBox.Show(e.Message); }
Aber der
CommandBuilder erzeugt die Insert-/Update-/Delete-Befehle nicht, obwohl sich jeder DataAdapter auf genau eine Tabelle bezieht und stets eine PrimaryKey mit einer ID definiert ist.
Bei einem
DB-spezifischen CommandBuilder wird (in Doku und Literatur) immer von folgender Reihenfolge ausgegangen (Beispiel aus
FB-Net-Provider):
Code:
FbConnection myConn = new FbConnection(myConnection);
FbDataAdapter myDataAdapter = new FbDataAdapter();
myDataAdapter.SelectCommand = new FbCommand("SELECT ...", myConn);
FbCommandBuilder custCB = new FbCommandBuilder(myDataAdapter);
// Select ausführen
myConn.Open();
myDataAdapter.Fill(custDataSet, "Employee");
myConn.Close();
Aber auch eine andere Reihenfolge meiner Befehle oder der Ersatz durch
FB-spezifische Anweisungen hat die benötigten Befehle nicht erzeugt:
Code:
// nach Zeile 3 im zweiten Schnipsel:
cmdb[x1] = new
fb.FbCommandBuilder(da[x1] as
fb.FbDataAdapter);
Auch der explizite Aufruf von cmdb[x1].RefreshSchema() bringt nichts (abgesehen davon, dass die NET- und
FB-Hilfen sich zu widersprechen scheinen: NET sagt "werden alle DbCommand-Objekte entfernt",
FB sagt "Refreshes the database schema information used to generate INSERT, UPDATE, or DELETE statements.").
Bei der
DB-unabhängigen Lösung kann ich
nicht DbCommandBuilder(myDataAdapter) verwenden, sondern muss mit
dataFactory.CreateCommandBuilder() arbeiten und danach DataAdapter zuweisen. Wie kann ich dafür sorgen, dass die benötigten Befehle erstellt werden? Oder könnte es sein, dass die
FB-Version noch nicht implementiert ist (obwohl der Builder schon in Version 1.7 enthalten war)?
Danke für Tipps! Jürgen