I'm filling gridview from mysql table
public void Init()
{
DataSet dataset = new DataSet();
dataset = FillGrid();
bindingSorce.DataSource = dataset.Tables[0];
gridControl1.DataSource = bindingSorce;
}
public static DataSet FillGrid()
{
MySqlConnection newConnection = new MySqlConnection(_connectionString);
try
{
DataSet dataset = new DataSet();
newConnection.Open();
if (newConnection.State.ToString() == "Open")
{
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = newConnection;
cmd.CommandText = "SELECT * FROM main";
MySqlDataAdapter adapter = new MySqlDataAdapter(cmd);
adapter.Fill(dataset);
}
else
{
return null;
}
newConnection.Close();
return dataset;
}
catch { return null; }
}
After any changes I'm trying to update mysql table
private void gridView1_RowUpdated(object sender, EventArgs e)
{
try
{
BindingSource bs = (BindingSource)gridView1.DataSource;
DataTable changes = ((DataTable)bs.DataSource).GetChanges();
if (changes != null)
{
bool asd = UpdateGrid(changes);
((DataTable)((BindingSource)gridView1.DataSource).DataSource).AcceptChanges();
}
}
catch { }
}
public static bool UpdateGrid(DataTable datatable)
{
MySqlConnection newConnection = new MySqlConnection(_connectionString);
//try
{
newConnection.Open();
if (newConnection.State.ToString() == "Open")
{
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = newConnection;
cmd.CommandText = "SELECT * FROM main";
MySqlDataAdapter adapter = new MySqlDataAdapter(cmd);
MySqlCommandBuilder cmb = new MySqlCommandBuilder(adapter);
//adapter.UpdateCommand = cmb.GetUpdateCommand();
//adapter.Update(datatable);
cmb.GetUpdateCommand();
adapter.Update(datatable);
}
else
{
return false;
}
newConnection.Close();
return true;
}
// catch { return false; }
}
And table realy updating, but if after that I'll call Init() then FillGrid() will return dataset with right columns, but without rows!(dataset.tables[0].Rows.count = 0). After restart programm filling will work true, but again updating will have the same effect
I started facing the same issue you post here after upgrading the version of MySQL database.
I have developed a C# application that querys a MySQL database and fills several datagrids using MySqlDataAdapter Fill() method. The database version in development environment was MySQL Server 5.1.38. When I installed the final database in the server, I used the latest release of the same version, MySQL Server 5.1.73.
When I started testing the application, I started getting exactly the same problem: whenever any change on the data was made via the datagrid, the database updated correctly, but after that, any datagrid in the application querying the database returned 0 rows. After searching on the web I found only two or three posts refering to the same issue, but with no answer. By now, the only way to get rid of it was uninstalling the upgrade 5.1.73 and installing the 5.1.38 version again.
Related
I am creating an airline booking system and I have 2 combo boxes. The first is for Departure City and the second is for Arrival City. I want to be able to eliminate the choice in the first combo box from the second, as I don't want the same city to be able to be submitted as both the departure and arrival city. I am querying the city names from a database.
Here is my code:
public partial class main : Form
{
public main()
{
InitializeComponent();
string connectionString = #"Base Schema Name=cyanair;data source=C:\Users\Client 0819\source\repos\Cyanair\cyanair.db";
//Departure ComboBox
SQLiteConnection conn = new SQLiteConnection(connectionString);
try
{
conn.Open();
SQLiteCommand cmd = new SQLiteCommand();
cmd.Connection = conn;
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = "SELECT * FROM CyanairAirports";
SQLiteDataAdapter da = new SQLiteDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
comboDeparture.DataSource = dt;
comboDeparture.ValueMember = "Descriptions";
comboDeparture.DisplayMember = "Descriptions";
conn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
//Arrival ComboBox
private void comboDeparture_DisplayMemberChanged(object sender, EventArgs e)
{
string connectionString = #"Base Schema Name=cyanair;data source=C:\Users\Client 0819\source\repos\Cyanair\cyanair.db";
SQLiteConnection conn = new SQLiteConnection(connectionString);
**String city = comboDeparture.DisplayMember;**
try
{
conn.Open();
SQLiteCommand cmd = new SQLiteCommand();
cmd.Connection = conn;
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = "SELECT * FROM CyanairAirports WHERE Descriptions IS NOT '" + comboDeparture.SelectedValue.ToString() + "'";
richTextBox1.Text = "SELECT * FROM CyanairAirports WHERE Descriptions IS NOT '" + comboDeparture.SelectedValue + "'";
SQLiteDataAdapter da = new SQLiteDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
comboArrival.DataSource = dt;
comboArrival.ValueMember = "Descriptions";
comboArrival.DisplayMember = "Descriptions";
conn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Thanks :)
It looks like you're handling the DisplayMemberChanged event on comboDeparture, and trying to update the values of comboArrival in that handler. However, DisplayMemberChanged only triggers when the DisplayMember property changes.
DisplayMember only tells the control which property to display on a data bound control. It isn't tied to the index or value selected in the ComboBox. So, the only time the code to populate comboArrival runs is in the constructor when you set comboDepartarture.DisplayMember. Instead, handle either ComboBox.SelectedIndexChanged or ComboBox.SelectedValueChanged and set the items of comboArrival.
A few other important things to note about your code.
First, you should use a parameterized query when running Sql Statements, rather than concatenating strings. Concatenating strings as you're doing opens you up to SQL Injection Attacks. I'm not familiar with SqlLite and can't provide you with an example of how to modify your code, but perhaps this question can help.
Second, you don't need to re-run the query every time you change the selected value in comboDeparture. Just add comboArrival's data source as a field on the Form and you can filter it. For example...
public partial class main : Form
{
// Your constructors...
private void comboDepartures_SelectedIndexChanged(object sender, EventArgs e)
{
if (_arrivalsDataSource == null)
{
_arrivalsDataSource = new System.Data.DataTable();
// Load _arrivalsDataSource from the database, basically how you're doing it now.
comboArrival.DataSource = _arrivalsDataSource.DefaultView;
comboArrival.DisplayMember = "Descriptions"
comboArribal.ValueMember = "Descriptions"
}
if (comboDeparture.SelectedIndex == -1)
{
_arrivalsDataSource.DefaultView.RowFilter = null; // Clear the filter.
}
else
{
// Set the filter.
_arrivalsDataSource.DefaultView.RowFilter = $"Description <> '{comboDeparture.SelectedValue}'";
}
}
private System.Data.DataTable _arrivalsDataSource = null;
}
I am using two combo boxes in one of my programs. The first combo box contains the products while the second contains the categories. I have a method which loads he categories on the second combo box from the database when ever a new item is selected on the first combo box "products". The first time i run the program and select an item it loads from the database but if i try it again nothing loads. Please help with what might be causing this.
private void load_schemes(object sender, EventArgs e)
{
DataTable subjects = new DataTable();
DBConnect con = new DBConnect();
using (SqlConnection CONN = con.getConnection())
{
try
{
schemename.Items.Clear();
SqlDataAdapter adapter = new SqlDataAdapter();
String schemeType = schemetype.Text;
firstname.Text = schemetype.Text;
String SQL = "";
if (schemeType == "Family Scheme")
{
SQL = "select schemeID,SCHEMENAME from registration.familyMedicalScheme";
}
else if (schemeType == "Insurance Scheme")
{
SQL = "select schemeID,SCHEMENAME from registration.insurancescheme";
}
else if (schemeType == "Company Scheme")
{
SQL = "select schemeID,SCHEMENAME from registration.companymedicalscheme";
}
adapter.SelectCommand = new SqlCommand(
SQL, CONN);
adapter.Fill(subjects);
schemename.DataSource = subjects;
schemename.DisplayMember = "SCHEMENAME";
//schemename.ValueMember = subjects.;
}
catch (Exception ex)
{
// Handle the error
}
finally
{
CONN.Close();
}
}
}
I changed the solution and used Items.Add instead of data binding method and it is now working
adapter.Fill(subjects);
foreach (DataRow da in subjects.Rows)
{
schemename.Items.Add(da[0].ToString());
}
I am now working on a little project on school in WPF using SQLite. I have an SQLite table that has these fields: id (primary key), name, sex, station, job, and date. I have a DataGrid that has the sex, station, and job as ComboBoxes. When I save the data from my table in an ObservableCollection, then the data loading in the DataGrid works great. My problem is now when I want to modify the values from the DataGrid in the SQLite table. Any idea would be nice.
Here's what I tried so far.
public SQLiteConnection m_db = new SQLiteConnection("Data Source=MyDatabase.sqlite;Version=3;");
SQLiteDataAdapter adap;
DataSet ds;
DataTable dt;
SQLiteCommandBuilder cmdbl;
string Query;
public MainWindow()
{
InitializeComponent();
dataGrid.ItemsSource = Userss.GetValues();
ds = new DataSet();
dataGrid.BeginInit();
ds.Tables.Add(CreateTable());
dataGrid.DataContext = ds.Tables[0];
dataGrid.EndInit();
}
public DataTable CreateTable()
{
m_db.Open();
Query = "Select * from user";
adap = new SQLiteDataAdapter(Query, m_db);
dt = new DataTable();
adap.Fill(dt);
m_db.Close();
return dt;
}
private void Update_Click(object sender, RoutedEventArgs e)
{
if (MessageBox.Show("Are you sure you want to make those changes?", "Please confirm", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
try
{
dt = dataGrid.DataContext as DataTable;
cmdbl = new SQLiteCommandBuilder(adap);
adap.Update(dt);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
else
this.dataGrid.CancelEdit();
}
When I press the Update button, the DB table remains the same.
The ObservableCollection works well.
Function getValues() from userss class
public static ObservableCollection<Userss> GetValues()
{
m_dd.Open();
string sql = "select * from user";
userCol.Clear();
SQLiteCommand cmd = new SQLiteCommand(sql, m_dd);
SQLiteDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
string sex1 = reader["sex"].ToString();
string station1 = reader["station"].ToString();
string job1 = reader["job"].ToString();
string data1 = reader["date"].ToString();
userCol.Add(new Userss()
{
Id = Convert.ToInt32(reader["id"]),
Name = reader["name"].ToString(),
Sex = (Sex)Enum.Parse(typeof(Sex), sex1),
Station = (Stations)Enum.Parse(typeof(Stations), station1),
Job = (Jobs)Enum.Parse(typeof(Jobs), job1),
Date = Convert.ToDateTime(data1)
});
}
m_dd.Close();
return userCol;
}
I'm attempting to fill a DataTable with results pulled from a MySQL database, however the DataTable, although it is initialised, doesn't populate. I wanted to use this DataTable to fill a ListView. Here's what I've got for the setting of the DataTable:
public DataTable SelectCharacters(string loginName)
{
this.Initialise();
string connection = "0.0.0.0";
string query = "SELECT * FROM characters WHERE _SteamName = '" + loginName + "'";
if (this.OpenConnection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, connection);
MySqlDataAdapter returnVal = new MySqlDataAdapter(query,connection);
DataTable dt = new DataTable("CharacterInfo");
returnVal.Fill(dt);
this.CloseConnection();
return dt;
}
else
{
this.CloseConnection();
DataTable dt = new DataTable("CharacterInfo");
return dt;
}
}
And for the filling of the ListView, I've got:
private void button1_Click(object sender, EventArgs e)
{
string searchCriteria = textBox1.Text;
dt = characterDatabase.SelectCharacters(searchCriteria);
MessageBox.Show(dt.ToString());
listView1.View = View.Details;
ListViewItem iItem;
foreach (DataRow row in dt.Rows)
{
iItem = new ListViewItem();
for (int i = 0; i < row.ItemArray.Length; i++)
{
if (i == 0)
iItem.Text = row.ItemArray[i].ToString();
else
iItem.SubItems.Add(row.ItemArray[i].ToString());
}
listView1.Items.Add(iItem);
}
}
Is there something I'm missing? The MessageBox was included so I could see if it has populated, to no luck.
Thanks for any help you can give.
Check your connection string and instead of using
MySqlCommand cmd = new MySqlCommand(query, connection);
MySqlDataAdapter returnVal = new MySqlDataAdapter(query,connection);
DataTable dt = new DataTable("CharacterInfo");
returnVal.Fill(dt);
this.CloseConnection();
return dt;
you can use this one
MySqlCommand cmd = new MySqlCommand(query, connection);
DataTable dt = new DataTable();
dt.load(cmd.ExecuteReader());
return dt;
Well, I ... can't figure out what you have done here so I'll paste you my code with which I'm filling datagridview:
1) Connection should look something like this(if localhost is your server, else, IP adress of server machine):
string connection = #"server=localhost;uid=root;password=*******;database=*******;port=3306;charset=utf8";
2) Query is ok(it will return you something), but you shouldn't build SQL statements like that.. use parameters instead. See SQL injection.
3) Code:
void SelectAllFrom(string query, DataGridView dgv)
{
_dataTable.Clear();
try
{
_conn = new MySqlConnection(connection);
_conn.Open();
_cmd = new MySqlCommand
{
Connection = _conn,
CommandText = query
};
_cmd.ExecuteNonQuery();
_da = new MySqlDataAdapter(_cmd);
_da.Fill(_dataTable);
_cb = new MySqlCommandBuilder(_da);
dgv.DataSource = _dataTable;
dgv.DataMember = _dataTable.TableName;
dgv.AutoResizeColumns();
_conn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
if (_conn != null) _conn.Close();
}
}
So, every time I want to display some content of table in mysql database I call this method, pass query string and datagridview name to that method. and, that is it.
For your sake, compare this example with your and see what can you use from both of it. Maybe, listview is not the best thing for you, just saying ...
hope that this will help you a little bit.
Debug your application and see if your sql statement/ connection string is correct and returns some value, also verify if your application is not throwing any exception.
Your connection string is invalid.
Set it as follows:
connection = "Server=myServer;Database=myDataBase;Uid=myUser;Pwd=myPassword;";
Refer: mysql connection strings
Here the following why the codes would not work.
Connection
The connection of your mySQL is invalid
Query
I guess do you want to search in the table, try this query
string query = "SELECT * FROM characters WHERE _SteamName LIKE '" + loginName + "%'";
notice the LIKE and % this could help to list all the data. for more details String Comparison Functions
I've been working on this since yesterday and I just can't update my database.
There are 3 tables. Here is a piece of code of one of WinForms. It loads data and display but after changing sth manually in the grid I get either errors by calling Update or anything happens at all.
please help because I'm going crazy.
public partial class Form3 : Form
{
//instance fields
private export2Excel export2XLS;
private DataSet _dataSet;
private BindingSource _bsrc;
private OleDbDataAdapter _dAdapter;
private OleDbCommandBuilder _cBuilder;
private DataTable _dTable;
private void button1_Click(object sender, EventArgs e)
{
//create the connection string
string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data
Source='C:\\Documents and Settings\\dorota\\Moje dokumenty\\Visual Studio
2010\\Projects\\WindowsFormsApplication1\\WindowsFormsApplication1\\artb.mdb'";
//create the database query
string query = "SELECT * FROM Samochody";
System.Data.DataSet DtSet = new System.Data.DataSet();
_dataSet = DtSet;
//create an OleDbDataAdapter to execute the query
OleDbDataAdapter dAdapter = new OleDbDataAdapter(query, connString);
dAdapter.FillSchema(_dataSet, SchemaType.Source);
_dAdapter = dAdapter;
//create a command builder
OleDbCommandBuilder cBuilder = new OleDbCommandBuilder(_dAdapter);
_cBuilder = cBuilder;
//create a DataTable to hold the query results
DataTable dTable = new DataTable();
_dTable = dTable;
//fill the DataTable
_dAdapter.Fill(_dTable);
//_dAdapter.TableMappings.Add("Samochody", "Table");
_dAdapter.Fill(_dataSet);
// --------------------- to datagridview !
//BindingSource to sync DataTable and DataGridView
BindingSource _bsrc = new BindingSource();
//set the BindingSource DataSource
//bSource.DataSource = _dTable;
_bsrc.DataSource = _dTable;
//_bsrc = bSource;
//set the DataGridView DataSource
dataGridView1.DataSource = _bsrc;
}
}
and here... :
private void sqlsave_Click(object sender, EventArgs e)
{
//int i=_dAdapter.Update(_dTable);
_dAdapter.Update(_dataSet.Tables["Samochody"]);
//_dAdapter.Update(_dataSet,"Samochody");
}
//---------------------------------------------------------------------------------
ok. I have changed sqlsave method for this
private void sqlsave_Click(object sender, EventArgs e)
{
try
{
//_dAdapter.Update(_dataSet.Tables["Samochody"]);
OleDbCommand oldb= _cBuilder.GetUpdateCommand();
int i=oldb.ExecuteNonQuery();
System.Windows.Forms.MessageBox.Show(i+" rows affected.");
//_dAdapter.Update(_dataSet,"Samochody");
}catch(OleDbException oldbex){
System.Windows.Forms.MessageBox.Show(oldbex.ToString());
}
and now I get finally sth more informative than "Error in"
An unhandled exception of type 'System.InvalidOperationException'
occurred in System.Data.dll Additional information: ExecuteNonQuery
requires an open and available Connection. The connection's current
state is closed.
so let me changed sth and I will let you know if this is it!
//--------------------------------
no. no. too fast, can't last. now while trying to save I've got exception again,
connectin is opened, but (I can't post the image) when I debug this I see that my object of OleDbCommand type as _commandText has
"UPDATE Samochody SET Item=?, Data dyspozycji autem od=?, ..."
and so on.
I think this is the reason. Am I right? What to do?
You didn't provide a connection for your OleDbDataAdapter. Try it something like this:
The example is different from your code but it shows the declaration of New Connection and passing it to the OleDbDataAdapter
string connetionString = null;
OleDbConnection connection ;
OleDbDataAdapter oledbAdapter ;
OleDbCommandBuilder oledbCmdBuilder ;
DataSet ds = new DataSet();
int i = 0;
string sql = null;
connetionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Your mdb filename;";
connection = new OleDbConnection(connetionString);
sql = "select * from tblUsers";
try
{
connection.Open(); // your code must have like this
oledbAdapter = new OleDbDataAdapter(sql, connection);
oledbCmdBuilder = new OleDbCommandBuilder(oledbAdapter);
oledbAdapter.Fill(ds);
for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
ds.Tables[0].Rows[i].ItemArray[2] = "neweamil#email.com";
}
oledbAdapter.Update(ds.Tables[0]);
connection.Close();
MessageBox.Show ("Email address updates !");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
I've found the answer:
But a better approach would be to use drag-and-drop and learn form the code.
Select Data|View Datasources. Your dataset should be visible in the DataSources Window.
Drag a table to a (new) form. VS2005 will add a load of components and a few lines of code.
The form will now have a instance of the dataset and that is your reference point for Adapter.Fill and .Update methods.
Easy and works great! : D
I've found it here: https://stackoverflow.com/a/548124/1141471