遇到MySQL异常问题

时间:2018-11-26 14:05:16

标签: c# mysql wpf

我正在尝试制作WPF应用程序。我的窗口内有一个数据网格。我创建了另一个将新数据添加到我的数据网格的窗口。尽管它可以像我想要的那样工作,但我总是遇到异常。我的MySQL代码:

using System;
using MySql.Data.MySqlClient;
using MySql.Data;
using System.Windows;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics;
using System.Windows.Controls;
using System.Data;
using Newtonsoft.Json;

namespace TestApp
{

    public class MySQLConnection
    {
        private MySqlConnection connection;
        private string server;
        private string database;
        private string user;
        private string password;
        private int port;
        private string sslM;
        private MySqlDataAdapter adp;
        private MySqlCommandBuilder builder;
        //Constructor
        public MySQLConnection()
        {
            Initialize();
        }

        //Initialize values
        private void Initialize()
        {
            server = "localhost";
            database = "pia";
            user = "root";
            password = "Timjar00";
            port = 3306;
            sslM = "None";
            string connectionString;
            connectionString = string.Format("server={0};port={1};user id={2}; password={3}; database={4}; SslMode={5}", server, port, user, password, database, sslM);

            connection = new MySqlConnection(connectionString);
        }

        //open connection to database
        private bool OpenConnection()
        {
            try
            {
                connection.Open();
                return true;
            }
            catch (MySqlException ex)
            {
                switch (ex.Number)
                {
                    case 0:
                        MessageBox.Show("Cannot connect to server.  Contact administrator");
                        break;

                    case 1045:
                        MessageBox.Show("Invalid username/password, please try again");
                        break;
                }
                return false;
            }
        }

        public void updateDatatable(DataTable tb,DataGrid dg)
        {
            try
            {
                builder = new MySqlCommandBuilder(adp);
                adp.Update(tb);
                dg.ItemsSource = tb.DefaultView;
            }
            catch(Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }

        public DataTable FillDataTable(string query, DataTable tb)
        {
            if (this.OpenConnection() == true)
            {
                try
                {
                    MySqlCommand cmd = new MySqlCommand(query, connection);
                    adp = new MySqlDataAdapter(cmd);
                    adp.Fill(tb);
                    adp.Dispose();
                    this.CloseConnection();
                }
                catch(MySqlException ex)
                {
                    MessageBox.Show(ex.Message);
                }

            }
            return tb;
        }



        //Close connection
        private bool CloseConnection()
        {
            try
            {
                connection.Close();
                return true;
            }
            catch (MySqlException ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }
        }



        public void CreateTableIfNotExists(string query)
        {
            //string query = "CREATE TABLE testtable (name varchar(20));";

            //open connection
            if (this.OpenConnection() == true)
            {
                //create command and assign the query and connection from the constructor
                MySqlCommand cmd = new MySqlCommand(query, connection);

                //Execute command
                cmd.ExecuteNonQuery();

                //close connection
                this.CloseConnection();
            }
        }

        //Insert statement
        public void Query(string query)
        {
            //open connection
            if (this.OpenConnection() == true)
            {
                //create command and assign the query and connection from the constructor
                MySqlCommand cmd = new MySqlCommand(query, connection);

                //Execute command
                cmd.ExecuteNonQuery();

                //close connection
                this.CloseConnection();
            }
        }

        //Insert statement
        public void InsertmultipleOne(string query, int amount)
        {
            //open connection
            if (this.OpenConnection() == true)
            {

                //create command and assign the query and connection from the constructor
                for(int i = 1; i <= amount; i++)
                {
                    string quer = string.Format(query, i);
                    MySqlCommand cmd = new MySqlCommand(quer, connection);
                    //Execute command
                    cmd.ExecuteNonQuery();
                }

                //close connection
                this.CloseConnection();
            }
        }

        public void InsertmultipleTwo(string query, int amount1, int amount2)
        {
            //open connection
            if (this.OpenConnection() == true)
            {
                //create command and assign the query and connection from the constructor
                for (int i = 1; i <= amount1; i++)
                {
                    string quer = string.Format(query, amount2,i);
                    MySqlCommand cmd = new MySqlCommand(quer, connection);
                    //Execute command
                    cmd.ExecuteNonQuery();
                }

                //close connection
                this.CloseConnection();
            }
        }
        public void InsertMultipleThree(string query,string val1, string val2, string val3, string val4, string val5, string val6, string val7, string val8, string val9, bool? val10, bool? val11, bool? val12)
        {
            if(this.OpenConnection() == true)
            {
                //create command and assign the query and connection from the constructor
                MySqlCommand command = new MySqlCommand(query, connection);
                command.Prepare();
                command.Parameters.AddWithValue("@DQvalue", val1.ToString());
                command.Parameters.AddWithValue("@DQIndexOf", val2.ToString());
                command.Parameters.AddWithValue("@DIvalue", val3.ToString());
                command.Parameters.AddWithValue("@DIIndexOf", val4.ToString());
                command.Parameters.AddWithValue("@AQvalue", val5.ToString());
                command.Parameters.AddWithValue("@AQIndexOf", val6.ToString());
                command.Parameters.AddWithValue("@AIvalueLoHi", val7.ToString());
                command.Parameters.AddWithValue("@AIIndexOf", val8.ToString());
                command.Parameters.AddWithValue("@description", val9.ToString());
                command.Parameters.AddWithValue("@checkBit", val10);
                command.Parameters.AddWithValue("@GND1", val11);
                command.Parameters.AddWithValue("@GND2", val12);
                //Execute command
                command.ExecuteNonQuery();

                //close connection
                this.CloseConnection();
            }
        }

        //Insert statement
        public void ReadQueryToComboBox(string query, ComboBox cb,string columnName)
        {
            //open connection
            if (this.OpenConnection() == true)
            {
                //create command and assign the query and connection from the constructor
                MySqlCommand cmd = new MySqlCommand(query, connection);
                MySqlDataReader rdr = cmd.ExecuteReader();
                while (rdr.Read())
                {
                    cb.Items.Add(rdr[columnName]);
                }
                //Execute command
                cmd.ExecuteNonQuery();
                rdr.Close();

                //close connection
                this.CloseConnection();
            }
        }


        //Select statement
        public List<string>[] Select()
        {
            string query = "SELECT * FROM tableinfo";

            //Create a list to store the result
            List<string>[] list = new List<string>[3];
            list[0] = new List<string>();
            list[1] = new List<string>();
            list[2] = new List<string>();

            //Open connection
            if (this.OpenConnection() == true)
            {
                //Create Command
                MySqlCommand cmd = new MySqlCommand(query, connection);
                //Create a data reader and Execute the command
                MySqlDataReader dataReader = cmd.ExecuteReader();

                //Read the data and store them in the list
                while (dataReader.Read())
                {
                    list[0].Add(dataReader["id"] + "");
                    list[1].Add(dataReader["name"] + "");
                    list[2].Add(dataReader["age"] + "");
                }

                //close Data Reader
                dataReader.Close();

                //close Connection
                this.CloseConnection();

                //return list to be displayed
                return list;
            }
            else
            {
                return list;
            }
        }

        //Count statement
        public int CountTable(string tablaname)
        {
            string query = string.Format("SELECT Count(*) FROM {0}", tablaname);
            int Count = -1;

            //Open Connection
            if (this.OpenConnection() == true)
            {
                //Create Mysql Command
                MySqlCommand cmd = new MySqlCommand(query, connection);

                //ExecuteScalar will return one value
                Count = int.Parse(cmd.ExecuteScalar() + "");

                //close Connection
                this.CloseConnection();

                return Count;
            }
            else
            {
                return Count;
            }
        }

        //Backup
        public void Backup()
        {
            try
            {
                DateTime Time = DateTime.Now;
                int year = Time.Year;
                int month = Time.Month;
                int day = Time.Day;
                int hour = Time.Hour;
                int minute = Time.Minute;
                int second = Time.Second;
                int millisecond = Time.Millisecond;

                //Save file to C:\ with the current date as a filename
                string path;
                path = "C:\\MySqlBackup" + year + "-" + month + "-" + day +
            "-" + hour + "-" + minute + "-" + second + "-" + millisecond + ".sql";
                StreamWriter file = new StreamWriter(path);


                ProcessStartInfo psi = new ProcessStartInfo();
                psi.FileName = "mysqldump";
                psi.RedirectStandardInput = false;
                psi.RedirectStandardOutput = true;
                psi.Arguments = string.Format(@"-u{0} -p{1} -h{2} {3}",
                    user, password, server, database);
                psi.UseShellExecute = false;

                Process process = Process.Start(psi);

                string output;
                output = process.StandardOutput.ReadToEnd();
                file.WriteLine(output);
                process.WaitForExit();
                file.Close();
                process.Close();
            }
            catch (IOException ex)
            {
                MessageBox.Show("Error , unable to backup!");
            }
        }

        //Restore
        public void Restore()
        {
            try
            {
                //Read file from C:\
                string path;
                path = "C:\\MySqlBackup.sql";
                StreamReader file = new StreamReader(path);
                string input = file.ReadToEnd();
                file.Close();

                ProcessStartInfo psi = new ProcessStartInfo();
                psi.FileName = "mysql";
                psi.RedirectStandardInput = true;
                psi.RedirectStandardOutput = false;
                psi.Arguments = string.Format(@"-u{0} -p{1} -h{2} {3}",
                    user, password, server, database);
                psi.UseShellExecute = false;


                Process process = Process.Start(psi);
                process.StandardInput.WriteLine(input);
                process.StandardInput.Close();
                process.WaitForExit();
                process.Close();
            }
            catch (IOException ex)
            {
                MessageBox.Show("Error , unable to Restore!");
            }
        }
    }
}

我将FillDataTable()方法绑定到了初始化代码。正确填充了DataGrid,但是当我打开一个新窗口向数据库添加新行时,我再次调用fillDataTable()函数。

我看到函数updateDatatable()立即跳转到我的异常中,并且不断出现以下异常:“已经有一个与此Connection关联的打开的DataReader,必须首先关闭它。”对于数据库中的每个记录,因此如果我有3行,则会显示3个消息框。我处理此类中的所有MySQL代码,并在其余代码中使用此类中的函数。

updateDataTable()函数内部有一个堆栈跟踪:

>   TestApp.exe!TestApp.MySQLConnection.updateDatatable(System.Data.DataTable tb, System.Windows.Controls.DataGrid dg) Line 79  C#
    TestApp.exe!TestApp.MainWindow.Row_Changed(object sender, System.Data.DataRowChangeEventArgs e) Line 178 + 0x2e bytes   C#
    System.Data.dll!System.Data.DataTable.OnRowChanged(System.Data.DataRowChangeEventArgs e) + 0x36 bytes   
    System.Data.dll!System.Data.DataTable.OnRowChanged(System.Data.DataRowChangeEventArgs args, System.Data.DataRow eRow, System.Data.DataRowAction eAction) + 0x4c bytes   
    System.Data.dll!System.Data.DataTable.RaiseRowChanged(System.Data.DataRowChangeEventArgs args, System.Data.DataRow eRow, System.Data.DataRowAction eAction) + 0xa8 bytes    
    System.Data.dll!System.Data.DataTable.SetNewRecordWorker(System.Data.DataRow row, int proposedRecord, System.Data.DataRowAction action, bool isInMerge, bool suppressEnsurePropertyChanged, int position, bool fireEvent, out System.Exception deferredException) + 0x21e bytes 
    System.Data.dll!System.Data.DataTable.InsertRow(System.Data.DataRow row, long proposedID, int pos, bool fireEvent) + 0xf5 bytes 
    System.Data.dll!System.Data.DataTable.LoadDataRow(object[] values, bool fAcceptChanges) + 0x178 bytes   
    System.Data.dll!System.Data.ProviderBase.SchemaMapping.LoadDataRow() + 0x67 bytes   
    System.Data.dll!System.Data.Common.DataAdapter.FillLoadDataRow(System.Data.ProviderBase.SchemaMapping mapping) + 0xc5 bytes 
    System.Data.dll!System.Data.Common.DataAdapter.FillFromReader(System.Data.DataSet dataset, System.Data.DataTable datatable, string srcTable, System.Data.ProviderBase.DataReaderContainer dataReader, int startRecord, int maxRecords, System.Data.DataColumn parentChapterColumn, object parentChapterValue) + 0xc6 bytes  
    System.Data.dll!System.Data.Common.DataAdapter.Fill(System.Data.DataTable[] dataTables, System.Data.IDataReader dataReader, int startRecord, int maxRecords) + 0x138 bytes  
    System.Data.dll!System.Data.Common.DbDataAdapter.FillInternal(System.Data.DataSet dataset, System.Data.DataTable[] datatables, int startRecord, int maxRecords, string srcTable, System.Data.IDbCommand command, System.Data.CommandBehavior behavior) + 0xab bytes 
    System.Data.dll!System.Data.Common.DbDataAdapter.Fill(System.Data.DataTable[] dataTables, int startRecord, int maxRecords, System.Data.IDbCommand command, System.Data.CommandBehavior behavior) + 0xa1 bytes   
    System.Data.dll!System.Data.Common.DbDataAdapter.Fill(System.Data.DataTable dataTable) + 0x6d bytes 
    TestApp.exe!TestApp.MySQLConnection.FillDataTable(string query, System.Data.DataTable tb) Line 93 + 0x10 bytes  C#
    TestApp.exe!TestApp.MainWindow.FillDatagrid() Line 193 + 0x2e bytes C#
    TestApp.exe!TestApp.MainWindow.Add_newRegel(object sender, System.Windows.RoutedEventArgs e) Line 769 + 0x8 bytes   C#
    PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) + 0x74 bytes    
    PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) + 0xae bytes   
    PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) + 0x73 bytes  
    PresentationCore.dll!System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs e) + 0x18 bytes 
    PresentationFramework.dll!System.Windows.Controls.Primitives.ButtonBase.OnClick() + 0x4b bytes  
    PresentationFramework.dll!System.Windows.Controls.Button.OnClick() + 0x55 bytes 
    PresentationFramework.dll!System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e) + 0xa6 bytes   
    PresentationCore.dll!System.Windows.UIElement.OnMouseLeftButtonUpThunk(object sender, System.Windows.Input.MouseButtonEventArgs e) + 0x6c bytes 
    PresentationCore.dll!System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(System.Delegate genericHandler, object genericTarget) + 0x30 bytes    
    PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) + 0x2e bytes  
    PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) + 0x3f bytes    
    PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) + 0xae bytes   
    PresentationCore.dll!System.Windows.UIElement.ReRaiseEventAs(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args, System.Windows.RoutedEvent newEvent) + 0x109 bytes    
    PresentationCore.dll!System.Windows.UIElement.OnMouseUpThunk(object sender, System.Windows.Input.MouseButtonEventArgs e) + 0xc6 bytes   
    PresentationCore.dll!System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(System.Delegate genericHandler, object genericTarget) + 0x30 bytes    
    PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) + 0x2e bytes  
    PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) + 0x3f bytes    
    PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) + 0xae bytes   
    PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) + 0x73 bytes  
    PresentationCore.dll!System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs args) + 0x46 bytes   
    PresentationCore.dll!System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs args, bool trusted) + 0x1a bytes    
    PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea() + 0x203 bytes   
    PresentationCore.dll!System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs input) + 0x45 bytes 
    PresentationCore.dll!System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport inputReport) + 0x62 bytes  
    PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.ReportInput(System.IntPtr hwnd, System.Windows.Input.InputMode mode, int timestamp, System.Windows.Input.RawMouseActions actions, int x, int y, int wheel) + 0x2d6 bytes 
    PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.FilterMessage(System.IntPtr hwnd, MS.Internal.Interop.WindowMessage msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) + 0x428 bytes 
    PresentationCore.dll!System.Windows.Interop.HwndSource.InputFilterMessage(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) + 0x6b bytes   
    WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) + 0x9b bytes    
    WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) + 0x6b bytes    
    WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) + 0x52 bytes 
    WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) + 0x34 bytes    
    WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) + 0x131 bytes 
    WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) + 0xee bytes 
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) + 0xb1 bytes  
    WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame) + 0x4a bytes  
    PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) + 0x5a bytes  
    PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) + 0x74 bytes 
    PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Window window) + 0x2b bytes 
    PresentationFramework.dll!System.Windows.Application.Run() + 0x1c bytes 
    TestApp.exe!TestApp.App.Main() + 0x59 bytes 

我也发现了我的问题所在。在我的主要代码中,我执行以下操作:

private void Add_newRegel(object sender, RoutedEventArgs e)
{
    ReceptenPopup recept = new ReceptenPopup();
    if (recept.ShowDialog() == true)
    {
    }
    else
    {
        dt.Clear();
        receptenDg.ItemsSource = null;
        sqlstring = "Select * FROM Recepten";
        DataTable mydt = db.FillDataTable(sqlstring, dt);
        receptenDg.ItemsSource = mydt.DefaultView;
        mydt.RowDeleted += Row_Deleted;
        mydt.RowChanged += Row_Changed;
    }
}

说明:当我打开一个新窗口时,填写信息,然后单击“确定”向数据库中添加新行,则else语句中的代码将被调用。代码中所有出错的部分是DataTable mydt = db.FillDataTable(sqlstring, dt);部分。我该如何解决?

1 个答案:

答案 0 :(得分:0)

连接,命令,数据读取器和数据适配器都是IDisposposable的,因此每个都应放在using块中。完成此操作后,无需关闭它们,因为它们将在退出该块时被隐式Dispose关闭。

它还保证即使抛出异常也不会处理,即使抛出异常也不会。任何实现此目的的替代方法最终都比using块更复杂,这使它变得轻而易举。

从将这些内容保留为类级字段后,您会发现这些问题将消失。

P.S。我建议不要命名仅通过 case 与其他类区别的类。

也值得一读can we stop using AddWithValue