Entwickler-Ecke

Datenbanken (inkl. ADO.NET) - C# und ODBC-Datenquellen


javafreak - Fr 11.04.08 09:50
Titel: C# und ODBC-Datenquellen
Hallo,

ich habe in der Systemsteuerung eine ODBC Verbindung erstellt. Aktuell z.B. mit einer MySQL (3.51) Datenbank. Name der Datenquelle: HugosDb Der Benutzer und das Passwort ist auch bei der ODBC Verbindung gespeichert.

Von Java aus kann ich mit diesem Code eine Verbindung herstellen und Queries absetzen:

Quelltext
1:
2:
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
con = DriverManager.getConnection("jdbc:odbc:HugosDb");

Bei C# funktioniert es mit

C#-Quelltext
1:
OdbcConnection con = new OdbcConnection("DRIVER={MySQL ODBC 3.51 Driver};SERVER=localhost;Database=HugosDb;User=root;Password=xxx;");                    

auch. Hat aber 2 gravierende Nachteile. Ich muss angeben welcher DB-Treiber verwendet wird und ich muss User und Passwort angeben. Bei der Java-Applikation könnte ich ohne Problem von einer MySQL auf Access, Oracle oder sonst was wechseln und müsste den Connection-String nicht anpassen. Bei C# wäre mit der Lösung eine Anpassung einer Config oder so notwendig.

Mit

C#-Quelltext
1:
OdbcConnection con = new OdbcConnection("DRIVER={MySQL ODBC 3.51 Driver};Dsn=HugosDb;");                    

bekomme ich die Fehlermeldung:

Quelltext
1:
ERROR [HY000] [MySQL][ODBC 3.51 Driver]Access denied for user 'ODBC'@'PUNISHER' (using password: NO)                    

Bitte nicht von dem Punisher statt localhost verwirren lassen. Das ganze geht über einen SSH-Tunnel auf eine MySQL-DB auf einem anderen Rechner. Dieser Tunnel funktioniert aber da ja die Java-Lösung und die C#-Lösung mit User/Passwd läuft.

Meine Frage also nun: Wie sieht der Connection String aus wenn ich über eine bereits angelegte ODBC-Datenquelle gehen will ohne weitere Angaben zu machen (welcher Treiber, User, Passwort)???

Danke schon im Voraus
Thomas


JüTho - Fr 11.04.08 10:21

Hallo,

grundsätzlich ist davon abzuraten, immer den Odbc-Provider zu verwenden: Für jedes DBMS gibt es optimierte DbProvider, zum Beispiel auch für MySql. Informationen über Möglichkeiten der Verbindung und DbProvider findest Du unter ConnectionStrings [http://www.connectionstrings.com/default.aspx?carrier=mysql].

Wenn Du variabel sein willst, bietet sich der Abschnitt ConnectionStrings der app.config an, siehe ConnectionStringSettings-Klasse. UserName und Password sollten natürlich (verschlüsselt) separat gespeichert und per Code eingefügt werden.

Ein mögliches Vorgehen wäre über eine separate Methode:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
DataTable GetData(string connectionString, string selectString) 
{
    DataTable result = new DataTable();
    using(DbConnection conn = new DbConnection(connectionString)) {
        DbDataAdapter da = new DbDataAdapter();
        DbCommand cmd = new DbCommand(selectString);
        cmd.Connection = conn;
        da.SelectCommand = cmd;
        da.Fill(result); 
    }
    return result;
}

An dieser Konstruktion ist normalerweise anstelle der Db-Klassen die spezielle MySql-Klasse zu verwenden (dann können auch mehrere Befehle zusammengefasst werden). Die allgemeinen Db-Klassen sind abstract und können so nicht verwendet werden!

Es gibt eine Alternative, die ich hier aber nur skizziere, weil sie vertieftes Verständnis erwartet: DbProviderFactories.GetFactory-Methode liefert DbProviderFactory, CreateConnection usw. liefern Instanzen, die wie Db-Klassen heißen und verwendet werden, aber tatsächlich spezielle Instanzen sind und akzeptiert werden.

Gruß Jürgen


maro158 - Fr 11.04.08 10:21

Folgender Code funktioniert auf meinem System anstandslos:


C#-Quelltext
1:
2:
3:
4:
5:
using (System.Data.Odbc.OdbcConnection connection = new System.Data.Odbc.OdbcConnection(@"DSN=HugosDb"))
{
   connection.Open();
   MessageBox.Show("Connection opened!");
}


Klappt es denn mit lokalen (nicht getunnelten) Verbindungen zu einem DSN?