我正在尝试制作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);
部分。我该如何解决?
答案 0 :(得分:0)
连接,命令,数据读取器和数据适配器都是IDisposposable的,因此每个都应放在using
块中。完成此操作后,无需关闭它们,因为它们将在退出该块时被隐式Dispose关闭。
它还保证即使抛出异常也不会处理,即使抛出异常也不会。任何实现此目的的替代方法最终都比using
块更复杂,这使它变得轻而易举。
从将这些内容保留为类级字段后,您会发现这些问题将消失。
P.S。我建议不要命名仅通过 case 与其他类区别的类。