Laden...

Wie kann ich ein WPF Projekt mit einer MySQL-Datenbank verbinden?

Erstellt von Wormtronic vor 3 Jahren Letzter Beitrag vor 3 Jahren 1.756 Views
W
Wormtronic Themenstarter:in
2 Beiträge seit 2020
vor 3 Jahren
Wie kann ich ein WPF Projekt mit einer MySQL-Datenbank verbinden?

verwendetes Datenbanksystem: mySQL v5.7.12
Visual Studio 2015 WPF-Projekt

Leider liefert der folgende C# Code immer eine Fehlermeldung> Fehlermeldung:

"System.InvalidOperationException: Schwerwiegender Fehler bei interner Verbindung. Fehlerzustand: 18"

Es wurden schon verschiedene connectionStrings mit verschiedenen mySQL Server versucht, mit dem gleichen Ergebnis.
Verbindung mit mySQL Browser funktioniert.


    private void btnDbVerbinden_Click(object sender, RoutedEventArgs e)
    {
      string connectionString;
      System.Data.SqlClient.SqlConnection cnn;

      //connectionString = tbConnectionString.Text.ToString();
      connectionString = @"server=localhost,3306;user id=testuser;password=testpassword;database=testdb";

      try
      {       
        cnn = new System.Data.SqlClient.SqlConnection(connectionString);
        cnn.Open();
        MessageBox.Show("Connection Open  !");
        cnn.Close();
      }
      catch (Exception except)
      {
        MessageBox.Show(except.ToString());
        //throw;
      }
      
    }

Fehlermeldung:
System.InvalidOperationException: Schwerwiegender Fehler bei interner Verbindung. Fehlerzustand: 18
bei System.Data.SqlClient.TdsParserStateObject.TryProcessHeader()
bei System.Data.SqlClient.TdsParser.ConsumePreLoginHandshake(SqlAuthenticationMethod authType, Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity, Boolean& marsCapable, Boolean& fedAuthRequired)
bei System.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity, Boolean withFailover, Boolean isFirstTransparentAttempt, SqlAuthenticationMethod authType, Boolean disableTnir, SqlAuthenticationProviderManager sqlAuthProviderManager)
bei System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover, Boolean isFirstTransparentAttempt, Boolean disableTnir)
bei System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout)
bei System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance)
bei System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, DbConnectionPool pool, String accessToken, Boolean applyTransientFaultHandling, SqlAuthenticationProviderManager sqlAuthProviderManager)
bei System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
bei System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
bei System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
bei System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
bei System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
bei System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection) bei System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
bei System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource1 retry, DbConnectionOptions userOptions) bei System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource1 retry, DbConnectionOptions userOptions)
bei System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource1 retry) bei System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource1 retry)
bei System.Data.SqlClient.SqlConnection.Open()
bei DBconnection.MainWindow.btnDbVerbinden_Click(Object sender, RoutedEventArgs e) in c:\users\wormtronic\documents\visual studio 2015\Projects\DBconnection\DBconnection\MainWindow.xaml.cs:Zeile 39.

Wo liegt der Fehler?

Gruß Wormtronic

M
368 Beiträge seit 2006
vor 3 Jahren

Es sollte localhost:3306 heissen (Doppelpunkt statt Komma): https://dev.mysql.com/doc/connector-net/en/connector-net-connections-string.html
Was andere Probleme (falscher Port, Treiber,...) aber nicht ausschliesst: https://stackoverflow.com/questions/32022580/failed-to-connect-to-mysql-at-localhost3306-with-user-root

Goalkicker.com // DNC Magazine for .NET Developers // .NET Blogs zum Folgen
Software is like cathedrals: first we build them, then we pray 😉

D
152 Beiträge seit 2013
vor 3 Jahren

Der von Dir verwendete Provider System.Data.SqlClient ist für MS SQL Server.
Für MySQL gibt es einen eignen Provider MySql.Data.

W
Wormtronic Themenstarter:in
2 Beiträge seit 2020
vor 3 Jahren

Es sollte localhost:3306 heissen (Doppelpunkt statt Komma):
>

Was andere Probleme (falscher Port, Treiber,...) aber nicht ausschliesst:
>

Danke für deine Hilfe,

aber bei
System.Data.SqlClient.SqlConnection
ist das Komma schon korrekt.
https://docs.microsoft.com/de-de/dotnet/api/system.data.sqlclient.sqlconnection.connectionstring?view=dotnet-plat-ext-3.1
Also:

connectionString = @"server=localhost,3306;user id=testuser;password=testpassword;database=testdb";

Bei
MySql.Data.MySqlClient.MySqlConnection
sollte der Port als Parameter angegeben werden.
https://dev.mysql.com/doc/dev/connector-net/8.0/html/P_MySql_Data_MySqlClient_MySqlConnection_ConnectionString.htm
Also:

 connectionString = @"server=localhost;port=3306;user id=testuser;password=testpassword;database=testdb";

Der von Dir verwendete Provider System.Data.SqlClient ist für MS SQL Server.
Für MySQL gibt es einen eignen Provider
>
.

Auch dir vielen Dank für deine Hilfe.
Hätte ich auch selber drauf kommen können. War wohl schon zu spät.

Hab jetzt die NuGet Package MySqlConnector installiert https://www.nuget.org/packages/MySqlConnector/0.69.3
und den Code wie folgt geändert.


    private void btnDbVerbinden_Click(object sender, RoutedEventArgs e)
    {
      string connectionString;
      //System.Data.SqlClient.SqlConnection cnn; // nicht für mySQL
      MySql.Data.MySqlClient.MySqlConnection cnn;


      //connectionString = tbConnectionString.Text.ToString();
      connectionString = @"server=localhost,3306;user id=testuser;password=testpassword;database=testdb"; // nicht für MySql.Data.MySqlClient.MySqlConnection
      connectionString = @"server=localhost;port=3306;user id=testuser;password=testpassword;database=testdb";

      try
      {       
        //cnn = new System.Data.SqlClient.SqlConnection(connectionString); // nicht für mySQL
        cnn = new MySql.Data.MySqlClient.MySqlConnection(connectionString);
        cnn.Open();
        MessageBox.Show("Connection Open  !");
        cnn.Close();
      }
      catch (Exception except)
      {
        MessageBox.Show(except.ToString());
        //throw;
      }
      
    }

T
2.222 Beiträge seit 2008
vor 3 Jahren

Kleiner Tipp, du musst die Datenbank Objekte(Connection, Command etc. auch disposen.
Nutzt dafür am besten ein using um die Objekte, dann sparst du dir auch ein extra Close Aufruf, da die Verbindungen beim disposen auch geschlossen werden.

Ebenfalls wird deine Verbindung im Fall eines Fehler aktuell nicht geschlossen, würde using in dem Fall für dich übernehmen.
Den ConnectionString solltest du auch nicht hard coden.
Sowas gehört in eine Config ausgelagert.

Ebenfalls sollte dein Datenbank Code nicht in der UI landen.
Schau dir dazu mal den Artikel für das Drei-Schichten Modell an.
Logik und Datenbankzugriffe gehören nicht in die UI und machen deinen Code auf lange Sichtunwartbar und nicht mal testbar.

[Artikel] Drei-Schichten-Architektur

Ebenfalls solltest du die Verbindung nicht offen halt, diese sollte nur für die jeweilige Aktion geöffnet, genutzt und geschlossen werden.
Nichts ist Schlimmer als eine ewig offene Verbindung.
Auch kann die Datenbank die Verbindung durch einen Neustart o.ä. trennen, dann arbeitest du auf einer toten Verbindung weiter.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.