Autor Beitrag
ene
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 779
Erhaltene Danke: 1

Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
BeitragVerfasst: Fr 21.08.09 09:14 
Angeregt durch JüTo's Einwurf zur Verwendung von Connection/Command/DataReader in einer using-Variante und diesem Thread, stellt sich mir die Frage, wie man das am Sinnvollsten umsetzt. Ich verknote mir da regelnmäßg das Hirn bei.

Ist es also sinnvoll sich eine Klasse wie folgt zu erstellen:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
static class clsDB
{
    public static string Connection = "";
    public static string Command = "";

    public static void Execute ()
    {
        using (OleDbConnection con = new OleDbConnection(Connection))
        using (OleDbCommand cmd = con.CreateCommand())
        {
            cmd.CommandText = Command;
            con.Open();
            cmd.ExecuteNonQuery();
        }
    }
}


Für ein einfaches Execute kein Problem, bei einem Datareader, bin ich mir dort aber nicht so sicher:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
public static OleDbDataReader CreateRecordset ()
{
    using (OleDbConnection con = new OleDbConnection(Connection))
    using (OleDbCommand cmd = con.CreateCommand())
    {
        cmd.CommandText = Command;
        con.Open();
        using (OleDbDataReader rs = cmd.ExecuteReader())
        {
            return rs;
        }
    }
}


Der Aufruf wäre dann ja auch ein using (OleDbDataReader dr = clsDB.CreateRecordset()). :gruebel:

_________________
Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Fr 21.08.09 11:35 
Hallo,

die Konstruktion ist im wesentlichen richtig (abgesehen davon, dass das Ganze als static-Bestandteile einer Klasse nicht so sinnvoll ist; aber ich nehme an, dass du das jetzt nur zu Demo-Zwecken so gebastelt hast).

Der DbDataReader macht es einem tatsächlich schwerer, weil er (wie in dem anderen Thread besprochen) die DbConnection häufig blockiert, bis er selbst geschlossen wird. Deshalb kann er auch nicht per return zurückgegeben werden, weil die DbConnection sofort geschlossen werden sollte und damit auch der Reader, der an diese DbConnection gebunden ist, verloren geht.

Die Lösung des Problems liegt darin, dass zwischen den verschiedenen Ebenen getrennt werden soll (am liebsten würde ich "muss" sagen, aber es kann abweichende Situationen geben): die Datenmenge im Arbeitsspeicher z.B. im typisierten DataSet auf der einen Seite, die Datenmenge auf der Festplatte (Datenbank) auf der anderen Seite. Die Verknüpfung zwischen beiden, z.B. eine Klasse für DbConnection und DbDataAdapter, füllt die Datenmenge im Arbeitsspeicher mit Werten - je nach Situation mit dem Rückgabewert einer DataTable oder mit einem einzelnen return-Wert oder mit einer List<T> als return-Wert oder mit Änderungen in einem DataSet oder was das Execute-Ergebnis sonst zurückliefert.

Ich hoffe, ich habe keine weitere Verwirrung hervorgerufen. Jürgen

PS. Lies übrigens auch einmal NET Richtlinien für Namen durch, vor allem hinsichtlich Groß- und Kleinschreibung.
ene Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 779
Erhaltene Danke: 1

Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
BeitragVerfasst: Fr 21.08.09 12:18 
Moin Jürgen,

Danke für die Antwort. Die Benamsung ist schon toll. Neues Framework neue Benamsung. Reddick ist für mich oft sinnvoller und lesbarer. Teile davon wurden wenigstens übernommen.

B2T: Der Code ist pseudomäßig aufgesetzt, wobei Verbesserungen gerne angebracht werden dürfen ;) Die static-Variante war eigentlich nur für den einfachen Aufruf. Das Problem ist halt jetzt, dass in der Klasse der Reader erzeugt und gefüllt wird. Aber ich kann halt das Object nicht losgelößt weitergeben. Das würde mir das Interface ersparen. In VBA gibt es die Möglichkeit von "ungebundenen" Recordset, was für manche Daten sehr sinnvoll ist. Ein Beispiel

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
Dim rs As ADODB.Recordset

Set rs = New ADODB.Recordset

rs.AcitveConnection = strConnection
rs.Open "SELECT * FROM Tabelle"
rs.ActiveConnection = Nothing


Damit behält der Recordset die Daten, aber die Connection kann geschlossen werden und man kann damit tun, was man will. In dem o.a. Beispiel muss ich es ja in ein anderes Objekt überführen:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
public DataTable CreateRecordset ()
{
    using (OleDbConnection con = new OleDbConnection(Connection))
    using (OleDbCommand cmd = con.CreateCommand())
    {
        cmd.CommandText = Command;
        con.Open();
        using (OleDbDataReader rs = cmd.ExecuteReader())
        {
            DataTable dt = new DataTable();
            dt.Load(rs);
            return dt;
        }
    }
}


Aber dadurch bin ich ja leider in der Rückgabe etwas eingeschränkter :(

_________________
Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Fr 21.08.09 18:15 
user profile iconene hat folgendes geschrieben Zum zitierten Posting springen:
Aber dadurch bin ich ja leider in der Rückgabe etwas eingeschränkter :(
Was genau meinst du? Bzw. wo siehst du Unterschiede zwischen RecordSet und DataTable (kenne nur letztere ;) )?

_________________
>λ=
ene Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 779
Erhaltene Danke: 1

Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
BeitragVerfasst: Mo 24.08.09 08:03 
Ne, war ein Denkfehler von mir :( Der DataTable ist ja auch ein losgelößtes Set. Mal sehen, wie weit ich heute komme ohne mir das Hirn erneut zu verknoten :)

_________________
Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.