1

I wrote a simple program that populates a Datagrid from MySQL.

In one of my columns I have a Boolean (0 or 1)

Once the Datagrid populates with the query I have check boxes for the boolean.

Does anyone know how to use a function when you check the check boxes for the boolean? (This is to send an update of just the boolean of the column.)

To sum up, When the check-box is checked it changes the boolean value from 0 to 1 in the MySQL database.

The reason I am having an issue with this is simply because the Datagrid does not populate until I run the application. Therefore, I cannot figure out how to change it while in visual studio.

How the DGV is populated:

MySqlConnection conn = new MySqlConnection(dbConnection);
conn.Open();
MySqlCommand cmd = new MySqlCommand();

cmd.Connection = conn;
MySqlDataAdapter da = new MySqlDataAdapter();

//SQL Query String
string sqlSelectAll = "SELECT * FROM `Tasks` WHERE `Completed` = 0";
da.SelectCommand = new MySqlCommand(sqlSelectAll, conn);

DataTable table = new DataTable();
da.Fill(table);

BindingSource bSource = new BindingSource();
bSource.DataSource = table;

dataGridView1.DataSource = bSource;

Any Help would be grateful.

Note:

I've tried using the data configuration manager in VS2015, which resulted in a completely different error that has nothing to do with this. So that's out of the question.

Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178
Mokey
  • 215
  • 1
  • 15
  • You need to clarify what you are asking. The checkbox represents the state of the bool column in the database, so of course you dont see it until the form loads and DGV populates. You can of course work with the *data* to do whatever, but it is not at all clear what that is ie `change it while in visual studio`. – Ňɏssa Pøngjǣrdenlarp Dec 29 '16 at 20:00
  • When you click the checkbox, I want it to change the boolean value within the mysql database. So I'm just trying to figure out how to do so. – Mokey Dec 29 '16 at 20:12
  • If you use a DataTable as a datasource when they click or change anything, the changes are stored in the DataTable - the DGV is just how we display data to users. Then using a DataAdapter those changes are written back to the DB. I suspect you are manually populating the DGV? – Ňɏssa Pøngjǣrdenlarp Dec 29 '16 at 20:15
  • Yes I am manually populating the DGV with code. – Mokey Dec 29 '16 at 20:21
  • That is how I am doing it. I edited the OP to show you the code. I thought there would be a onClick, onChanged or "onChecked" event I could add for just the boolean column . – Mokey Dec 29 '16 at 20:26
  • No, that code is populating the DGV using a DataSource - you are not manually adding rows one by one. If you persist that DataAdapter, you can use it to send changes back to the db. – Ňɏssa Pøngjǣrdenlarp Dec 29 '16 at 20:27
  • Makes logical sense... Guess I got some more googling to do. I guess I was just thinking about it in a different way. Thanks. – Mokey Dec 29 '16 at 20:30
  • 1
    [This answer should help you](http://stackoverflow.com/a/33702351/1070452) `da.Update(table);` – Ňɏssa Pøngjǣrdenlarp Dec 29 '16 at 20:31
  • Thanks a mil, this is what I wanted. – Mokey Dec 29 '16 at 20:38
  • Well if it helped, by all means click the upvote button for the answer. Upvoting posts which help or inform you helps others find good answers – Ňɏssa Pøngjǣrdenlarp Dec 29 '16 at 20:40
  • Yeah, I will.. I'm not a professional programmer, but I'm doing it as a project at work. So once I wrap my head around it and make sure it works I'll be sure to up vote. – Mokey Dec 29 '16 at 20:47
  • I guess I'm not really understanding it for mySQL. Is some documentation for this I can look into to try and understand how to do so better? – Mokey Dec 30 '16 at 14:17
  • It works exactly the same for MySQL just use MySQL provider objects. Except DataTable - those are agnostic – Ňɏssa Pøngjǣrdenlarp Dec 30 '16 at 15:05
  • I'm just lost on 'Dim myCB As New OleDbCommandBuilder(da)' from the response on the old OP. I'm not sure what 'dim' is. – Mokey Dec 30 '16 at 15:27
  • That is a VB answer; the c# version for MySQL would be `var myCB = new MySQLCommandBuilder(myda);`. You could run that block of code thru http://converter.telerik.com/ to get the c# syntax. Generally you can use `var` in place of Dim – Ňɏssa Pøngjǣrdenlarp Dec 30 '16 at 15:29
  • So that's something I seem to not need? So ideally I just need to add `my.DA.Update(myDT);`prior to the 'Fill' which I thought would work, but still it's not updating the database. – Mokey Dec 30 '16 at 15:46
  • You **do** want a command builder so that the DA knows how to perform updates, inserts and deletes for you. thats the point – Ňɏssa Pøngjǣrdenlarp Dec 30 '16 at 15:49
  • I rolled back your edit because it more or less invalidates the answer I took the time to post...the edit makes it look like the answer is not needed – Ňɏssa Pøngjǣrdenlarp Dec 30 '16 at 16:04
  • 1
    fair enough, again thanks and upvoted your OP too – Mokey Dec 30 '16 at 16:14
  • Thanks - if you had appended the new edit I would have left it alone, but obviously the missing ()s were apparent via the comment – Ňɏssa Pøngjǣrdenlarp Dec 30 '16 at 16:16

1 Answers1

1

If you were to persist that DataAdapter it will apply all changes to the underlying DataTable for you - multiples in fact:

First class level object to be reused:

public partial class Form1 : Form

    MySQLDataAdapter myDA;
    DataTable myDT;
    string dbConnStr = "server=..."

Then where you initialize everything:

string sql = "SELECT A, B, C, D... FROM `Tasks`";

// create the DT
myDT = new DataTable();

// The Adapter can create its own Connection 
//     and SelectCommand
myDA = new MySqlDataAdapter(sql, dbConnStr);

MySqlCommandBuilder cb = new MySqlCommandBuilder(myDA);

// "teach" the DA how to Update and Add:
myDA.UpdateCommand = cb.GetUpdateCommand();
myDA.InsertCommand = cb.GetInsertCommand();
myDA.DeleteCommand = cb.GetDeleteCommand();

myDA.Fill(myDT);
myDA.FillSchema(myDT, SchemaType.Source);

dgv1.DataSource = myDT;

This should create all the needed columns in the DGV and fill it with rows. That part you have/know. Click 2-3 checkboxes to change a value, then on a button press add this:

int rows = myDA.Update(myDT);

Under Debug if you examine the value of rows, it will be as many as the number of checkboxes you changed. It would also INSERT, DELETE or UPDATE any number of rows where that action was needed.

  • There is no need to create a connection. Using the MySqlDataAdapter(string, string) constructor overload, you pass the connection string and it creates a connection for itself to use.
  • Likewise, it creates a DBCommand object for the SELECT command
  • MySQLCommandBuilder then uses that SelectCommand to create Update, Delete etc commands the DataAdapter will use. This allows you to issue 1 (one) Update method call to update 1, 10 or 1000 rows.
  • When dealing with a single table, you may not need any other SQL in your app
  • The DataAdapter has the connection string, so it opens and closes its own connections.

If you define the PrimaryKey for the DataTable, the DA can also refresh the data - if changes are made to the table outside the app such as by another user, then you can pick up those new rows. After you update with your own changes:

var rows = myDA.Fill(myDT);

This is an actual refresh - it will only load new rows and any changes to any existing rows. Note that the WHERE clause in the original SQL still applies.

As you can see, the DataAdapter is capable of much more than just filling DataTables; if that is all you need to do, you can use a DbCommand and DataReader:

myDt.Load(cmd.ExecuteReader()):
Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178
  • Ok, I had the code pretty much exactly to this prior to the post :) however I'm having an issue with the command builder. the `cb.GetxCommand` is returning an error of `cannot convert method group GetxCommand to non-delegate type MySqlCommand. Did you intend to Invoke a Method?` This was what I couldn't understand ealer when I said That's something I seem not to need... – Mokey Dec 30 '16 at 15:55
  • They are methods, so they need `()` at the end - the `()` is optional in VB (I started with a quick translation from that VB answer). – Ňɏssa Pøngjǣrdenlarp Dec 30 '16 at 16:02
  • OMG, I'm such a ****head. Works perfectly.. I am so stupid. I can't believe I just asked that question... The whole time I was literally just missing `()` at the end of the method... and I knew what it meant. My brain is on auto pilot... However, I've learned a hell of a lot for datagrids because of you :) – Mokey Dec 30 '16 at 16:06
  • @ Plutonix, When you talk about if Changes were made via by other users to use the data adapter to refresh the page when this happens.... can you link me to some documentation? Are you referring to Parent and Child Keys via the DB or something else? – Mokey Jan 05 '17 at 18:04
  • No, if UserA adds a row to the FooBar table, you can 'pick up' those new rows in UserB's app instance using `Fill`, or if UserB change the status of something UserA can pick it up. Also applies to changes you might make in your UI DB Browser tool. Its all part of the DbDataAdapeter functionality – Ňɏssa Pøngjǣrdenlarp Jan 05 '17 at 18:15
  • I guess my question is, How do you define a key for the datagrid? I was assuming that you were speaking of foreign keys within the DB. – Mokey Jan 05 '17 at 19:04
  • You define the PK on the DataTable - the grids are just a user display mechanism. `myDT.PrimaryKey = New DataColumn[] {dtSample.Columns(0)}`. If the DA has multiple tables which are related you can define that as well wither as FKeys or Constraints – Ňɏssa Pøngjǣrdenlarp Jan 05 '17 at 19:14
  • A True Refresh means the DT picks up *just the changes* either new rows or new column values. Without the DA properly configured, you are reloading all the rows every time. *Another* way to do that is to write a little Table Monitor that fires an event when there are certain changes to a table – Ňɏssa Pøngjǣrdenlarp Jan 05 '17 at 19:25