Benutzer mit den meisten Antworten
CommandCollection bestimmen

Frage
-
Hallo!
Ich benutze ein typisiertes Dataset, welches eine Connection zu einem MS-SQL Server besitzt.
In (m)einem Tableadapter sind mehere SQL-Abfragen (GetData1...5) definiert.
Über die GetData()-Methode(n) des Tableadapters erstelle ich eine typisierte DataTable. (Soweit alles Standard)
Wie kann ich, ausgehend von der Instanz der erstellten Datatable, das SQL-Statement welches zum Datenabruf verwendet wurde, ermitteln? Also GetData1, GetData2, GetData3 oder ???
Über eine Instanz des Tableadapters kann ich ja die CommandCollection's (und damit die SQL-Statements [CommandText]) auslesen, die überhaupt bei diesem Tableadapter definiert sind. Aber wie erfahre ich, durch welches Command die DataTable-Instanz erstellt wurde?
Ziel des ganzen ist es, dass das SQL-Statement, welches zur akt. Tabelle geführt hat, in die Zwischenablage kopiert werden soll.
Antworten
-
Hallo Fred,
Man könnte ja auch Reflection verwenden, um an nicht-öffentliche Felder recht einfach heranzukommen. Wenn man's mit der Anzahl der Zugriffe über Reflection nicht übertreibt, bleibt das Ganze auch schön performant.
Das muss aber nicht sein! Denn in einer Methode wie GetData2 wird als erstes überhaupt eine Zeile wie folgende ausgeführt:
this.Adapter.SelectCommand = this.CommandCollection[1]
Damit ist das private Wissen über den spezifischen Index in das CommandCollection-Array wieder öffentlich geworden. Mit anderen Worten: Nachdem man adapter.GetData2() aufruft, befindet sich der CommandText im adapter.Adapter.SelectCommand-Eigenschaft:
AdventureWorksDataSetTableAdapters.CustomerTableAdapter adapter = new AdventureWorksDataSetTableAdapters.CustomerTableAdapter(); AdventureWorksDataSet.CustomerDataTable customersTable = adapter.GetData2(); MessageBox.Show(adapter.Adapter.SelectCommand.CommandText);
Jetzt mußt Du nur noch einen Wrapper um die Tabelle machen, wo Du CommandText speicher/abrufen kannst.
Gerne.
Gruß
Marcel
- Als Antwort markiert perlfred Montag, 7. Mai 2012 13:21
Alle Antworten
-
Hallo perlfred,
Soviel ich weiß, geht das standardmäßig gar nicht. Weder die konkrete typisierte Tabelle, noch ihre Basisklasse TypedTableBase<T> oder deren Basisklasse DataTable speichern auch nur den keinsten Verweis auf irgendeinen Adapter. Nur im Fall von DataTable.Load() wird intern ein Adapter instanziiert, aber auch das hilft dir nicht wirklich weiter. Der einzige Weg zum SQL-Statement zu kommen, von dem ich weiß, ist der über Command.CommandText, aber diese Eigenschaft ist aus der Tabelleninstanz nicht erreichbar.
Um doch noch an dein Ziel zu kommen, könntest Du eigene generische Adapter- und Table-Wrapper erstellen. Der Table-Wrapper würde eine Property zur Verfügung stellen, z.B. TableWrapper.SQLStatement und der Adapter-Wrapper (der IDbAdapter implementieren müßte) würde beim Aufruf von IDbAdapter.Fill() den Aufruf zunächst an den gewrappten Adapter delegieren, um dann die TableWrapper.SQLStatement-Eigenschaft zu setzen.
Gruß
Marcel -
Hallo Marcel!
Nur um auf die CommandCollection zugreifen zu können, muss man schon eine partial Class vom Tableadapter erstellen, da sie in einer anderen "Sicherheitsebene" (Daten-Thread?) eingebunden ist (per Debugger funktioniert es ohne Probleme!).
Wrapper zu erstellen, nur um das SQL-Statement zu erhalten, steht dann doch in keinem Verhältnis.
Trotzdem Danke für deine Bemühungen!!
Fred.
-
Hallo Fred,
Man könnte ja auch Reflection verwenden, um an nicht-öffentliche Felder recht einfach heranzukommen. Wenn man's mit der Anzahl der Zugriffe über Reflection nicht übertreibt, bleibt das Ganze auch schön performant.
Das muss aber nicht sein! Denn in einer Methode wie GetData2 wird als erstes überhaupt eine Zeile wie folgende ausgeführt:
this.Adapter.SelectCommand = this.CommandCollection[1]
Damit ist das private Wissen über den spezifischen Index in das CommandCollection-Array wieder öffentlich geworden. Mit anderen Worten: Nachdem man adapter.GetData2() aufruft, befindet sich der CommandText im adapter.Adapter.SelectCommand-Eigenschaft:
AdventureWorksDataSetTableAdapters.CustomerTableAdapter adapter = new AdventureWorksDataSetTableAdapters.CustomerTableAdapter(); AdventureWorksDataSet.CustomerDataTable customersTable = adapter.GetData2(); MessageBox.Show(adapter.Adapter.SelectCommand.CommandText);
Jetzt mußt Du nur noch einen Wrapper um die Tabelle machen, wo Du CommandText speicher/abrufen kannst.
Gerne.
Gruß
Marcel
- Als Antwort markiert perlfred Montag, 7. Mai 2012 13:21
-
Hallo Marcel!
Großartige Lösung!! myAdapter.Adapter.SelectCommand.CommandText
Ich rufe den zuletzt verwendeten CommandText jetz bei jedem SQL-Abruf vom aktuellen Tableadapter ab und speicher ihn in einer zentralen Variable. So kann ich ihn jederzeit bei Bedarf in die Zwischenablage kopieren.
Einen kleinen Schönheitsfehler gibt es zwar noch, da die Parameter im CommandText nicht gleich ersetzt werden sonder wirklich als Variablennamen angegeben werden. Da es unter Adapter aber auch die Parameter-Collection gibt, ist das eine reine Fleißaufgabe.
Vielen Dank für die wertvolle Lösung!!!!
Fred.