Allgemeiner Datenbankzugriff über ADO.NET => Providerproblem



  • Hallo,

    ich habe vor, mich in meinen Programmen nicht für eine Datenbank entscheiden zu müssen, sondern alle möglichen Datenbanken universell ansprechen zu können. Ich habe mich mal in die Problematik eingearbeitet und will nun ein Datenbankinterface schreiben, welches von 4 Datenbankklassen implementiert wird und die Funktionalität jedes Providers zur Verfügung stellt ( SqlClient, OracleClient, OledbClient und OdbcClient ).

    In der msdn habe dazu folgendes gefunden

    Die wichtigste Microsoft-Datenbank ist SQL Server, und SqlClient ist der Provider für SQL Server. ADO.NET 2.0 wird mit vier Microsoft-Providern geliefert:

    1. SqlClient - Der Microsoft-Provider für SQL Server

    2. OracleClient - Der Microsoft-Provider für die Oracle-Datenbank

    3. OleDb - Der Brückenprovider für die Verwendung von OLE DB-Providern in ADO.NET

    4. Odbc - Der Brückenprovider für die Verwendung von ODBC-Treibern in ADO.NET

    Wenn ich das richtig verstehe, nutze ich den SqlClient also nur für den MSSQL-Server, den OracleClient für Oracle, den OleDB Provider für ältere MSSQL-Server und den ODBC-Provider für alle anderen Datenbanken, beispielsweise für eine MySQL-Datenbank?

    Wäre für mich hilfreich, wenn dazu jemand mal Stellung beziehen könnte, ob ich das so richtig verstanden habe.



  • mit 3 und 4 kannst du imho alle DBs nutzen. musst halt nur nen ODBC Treiber etc dafür haben



  • ODBC wird da wohl die bessere wahl sein, allerdings wirst du dann noch auf probleme stossen mit sql, da fast jede db sein eigenes sql hat

    viel spass also noch 😉



  • Tequilla schrieb:

    ODBC wird da wohl die bessere wahl sein, allerdings wirst du dann noch auf probleme stossen mit sql, da fast jede db sein eigenes sql hat

    viel spass also noch 😉

    Bitte? Die SQL-Befehle sind doch soweit ich weiss für alle Datenbanken gleich, zumindest die standardisierten SQL-Kommandos. Oder sehe ich das falsch?



  • Polofreak schrieb:

    mit 3 und 4 kannst du imho alle DBs nutzen. musst halt nur nen ODBC Treiber etc dafür haben

    Das ist mir schon klar. Aber warum sollte ich ADO.NET benutzen, wenn ich sowieso über ODBC geben soll ?!



  • fluxy schrieb:

    Bitte? Die SQL-Befehle sind doch soweit ich weiss für alle Datenbanken gleich, zumindest die standardisierten SQL-Kommandos. Oder sehe ich das falsch?

    In der Theorie schon, ich hatte schon einige Probs wenn ich eine Anwendung von MySQL zb auf MSSQL umschrieb. Allerdings hab ich bis jetzt noch nicht mit ADO gearbeitet, von daher weiss ich nicht, ob es da besser ist.
    Kannst ja dann deine Erfahrung ja hier mal posten.

    Das Prob ist halt, das SQL zwar standardisiert ist, aber in einer sehr prohibitären Form. Und da ja jeder seine eigenen Features mit reinpacken will ist es halt gleich vorbei mit der standardkonformität.

    Ist wie HTML, ist eigentlich auch standardisiert aber trotzdem gibt es Unterschiede zwischen Netscape und IE zB



  • Benutze nicht ODBC für alle DBs!
    Schreibe Dir eine ProviderFactory ( in .NET 2.0 ist eine dabei ), aus der gibst Du dann die richtigen Instanzen zurück. Im Programm arbeitest Du dann mit den Schnittstellen, wie z.B. System.Data.IDbConnection oder der Klasse DbConnection.

    Edit:
    A Generic Data Access Component using Factory Pattern
    ProviderFactory



  • Noodles,

    das geht schon in die Richtung in die ich will. Ich will ein Allgemeines Datenbankinterface haben, über welches ich alle Datenbanken universell ansprechen kann.

    Allerdings mache ich das in Visual C++.NET ( ein Mod könnte das mal ins C++ / CLI Forum verschieben bitte ).

    Ich habe die Klassen zwar noch nicht implementiert, aber ich dachte mir das so, dass es eine Basisklasse gibt, die von 4 Klassen implementiert wird ( jeweils für SqlClient, OracleClient, OleDBClient und ODBCClient ). Zu implementieren wären im Prinzip eine startup-Methode, die eine Verbindung mittels dem connectionstring aufbaut, eine Methode die die verbindung wieder schliesst, eine methode die einen SQL-String übergeben bekommt und diesen ausführt ( für update-statements ) und eine Methode die eine SQL-Abfrage ausführt und nen ResultSet speichert, was von der DB zurückkommt. Zusätzlich bräuchte ich noch eine Methode um den Cursor auf den nächsten Datensatz im Resultset zu setzten sowie eine Methode um die Daten des aktuellen Satzes zurückzugeben. Und natürlich dann noch die Getter und Setter....

    Das Problem was ich im Moment habe ist, dass ich mit den OracleDataReader im moment arbeite ( und der OracleConnection bzw. OracleCommand ) wie heissen denn dazu die Basisklassen? Ich muss die Member in das Interface packen, und da muss ich Basisklassenpointer benutzen.

    Meint ihr das könnte man so implementieren?

    Was das SQL angeht, ja ich habe davon gehört das es bei Oracle oder MSSql z.B. spezifische SQL-Kommandos gibt aber das ist so wie damals mit Ansi-C um plattformunabhängig zu bleiben... Nen ZeroMemory liess sich auf Linux halt weniger kompilieren als ein memset... Von daher denke ich mal wenn man sich an den SQL-Standard hällt, sollte man keine Probleme bekommen.

    Gruß und danke schonmal an den Mod zum verschieben des topics ^^



  • Schau mal in die MSDN alle Klassen haben eine gemeinsame Basisklasse bzw. implementieren ein gemeinsames Interface. Einen Cursor brauchst Du nicht, ADO.NET ist verbindungslos. Du kannst Du Daten in einem DataSet halten, oder wenn Du nur lesen willst, in einem DataReader.



  • Das mit dem verbindungslosen habe ich schon gehört - aber ich will das erstmal verbindungsorientiert haben. Den DataReader benutze ich ja schon.

    Im moment mache ich das halt so:

    int main()
    {
    	OracleConnection*	ora_connection;
    	OracleCommand*		ora_command;
    	OracleDataReader*	ora_reader;
    
    	ora_connection = new OracleConnection (S"Data Source=termin;User ID=schabbach;Password=*********;");
    
    	try
    	{
    		ora_connection->Open ();
    		ora_command = new OracleCommand ( S"SELECT * FROM adresse" , ora_connection );
    
    		ora_reader = ora_command->ExecuteReader();
    
    		while ( ora_reader->Read() )
    		{
    			Console::WriteLine ( ora_reader->get_Item ( "NAME" )->ToString() );
    		}
    	}
    	catch ( Exception* e )
    	{
    		Console::WriteLine ( e->Message );
    	}
    
    	Console::WriteLine(S"Hello World");
    	Console::ReadLine();
    
    	return 0;
    }
    

    Aber wie gesagt, ich nutzte Visual C++.NET, also wäre wirklich sinnvoll das mal zu verschieben. Der Code ist nur ein Testcode, um mit einer Oracle-DB zu kommunizieren, ich will das ja später so haben, dass ich damit jede Tabelle und jede Datenbank ansprechen kann.

    Gruß Sebastian



  • Du siehst ja in meinen Links, wie man dieses Problem löst. Es ist ja kein sprachspezifisches Problem.


Anmelden zum Antworten