3

Im trying to build up a little status-tool. I need to get results of multiple queries (about 4-5). The general connection-setup and 'how-to-read-data' is already done but I cant figure out how the another query executed.

Everything I found while searching for it is for the SqlClient. Im totally overcharged with this.

Here is my code so far (be patient, im a newbie to this):

private void button1_Click(object sender, EventArgs e)
        {
            if(listView1.Items.Count > 1)
            {
                listView1.Items.Clear();
            }
            var listMember = new List<string>{};
            var listOnline = new List<string>{};

            // SQL PART //
            string connString = "Server=10*****;Port=3306;Database=e***;Uid=e***;password=********************;";
            MySqlConnection conn = new MySqlConnection(connString);
            MySqlCommand command = conn.CreateCommand();
            command.CommandText = "SELECT fullname,online FROM member WHERE active = '1' ORDER BY online DESC";
            try
            {
                conn.Open();
            }
            catch (Exception ex)
            {
                listView1.Items.Add("Error: " + ex);
            }
            MySqlDataReader reader = command.ExecuteReader();
            while(reader.Read())
            {
                listMember.Add(reader["fullname"].ToString());
                listOnline.Add(reader["online"].ToString());
            }
            conn.Close();
            // SQL ENDING //

            // SET ENTRIES TO LISTVIEW //
            int counter = 0;
            foreach(string member in listMember)
            {
                ListViewItem item = new ListViewItem(new[] { member, listOnline.ElementAt(counter) });
                item.ForeColor = Color.Green;
                listView1.Items.Add(item);

                counter++;
            }
        }

Im not really sure how the design/layout will look like in the end, so I would like to just append the results to lists in the sql-part to process the data later out of the lists.

Do I really have to setup a complete new connection after conn.Close()? Or is there any other way? I can just imagine: 5 queries with their own connection,try,catch and 2 loops... this will get about 100-200 lines just for getting the results out of 5 queries. Isnt that a bit too much for such an easy thing?

Hope for some help. Greetings.

According to the new comments my latest code:

Top:

public partial class Form1 : Form
{
    public static string connString = "Server=10****;Port=3306;Database=e****;Uid=e****;password=****;";
    public Form1()
    {
        InitializeComponent();
        MySqlConnection conn = new MySqlConnection(connString); // Error gone!
    }

Body part:

 public void QueryTwoFields(string s, List<string> S1, List<string> S2)
        {
            try
            {
                MySqlCommand cmd = conn.CreateCommand(); // ERROR: conn does not exist in the current context.
                cmd.CommandType = CommandType.Text;
                string command = s;
                cmd.CommandText = command;
                MySqlDataReader sqlreader = cmd.ExecuteReader();
                while (sqlreader.Read())
                {
                    S1.Add(sqlreader[0].ToString());
                    S2.Add(sqlreader[1].ToString());
                }
                sqlreader.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

private void button1_Click(object sender, EventArgs e)
        {
            if(listView1.Items.Count > 1)
            {
                listView1.Items.Clear();
            }
            var listMember = new List<string>{};
            var listOnline = new List<string>{};

            using (conn) // ERROR: conn does not exist in the current context.
            {
            conn.Open();
            ///...1st Query
            QueryTwoFields("SELECT fullname,online FROM member WHERE active = '1' ORDER BY online DESC",listMember,listOnline);
            //...2nd query
            //QueryTwoFields("your new Select Statement", otherList, otherList); 
            }
        }
C4d
  • 3,183
  • 4
  • 29
  • 50

2 Answers2

3

You don't have to close connection every time you execute one query rarher than close the sqlreader assigned to that connection. Finally when all of your queries have been executed you close the connection. Consider also the use of using:

You cal also define a method for execution your Query in order for your code not to be repetive:

    public  void QueryTwoFields(string s, List<string> S1, List<string> S2)    
///Select into List S1 and List S2 from  Database (2 fields)
              {
                  try
                  {             
                          MySqlCommand cmd = conn.CreateCommand();
                          cmd.CommandType = CommandType.Text;
                          string command = s;
                          cmd.CommandText = command;
                          MySqlDataReader sqlreader = cmd.ExecuteReader();
                          while (sqlreader.Read())
                          {
                              S1.Add(sqlreader[0].ToString());
                              S2.Add(sqlreader[1].ToString());            
                          }
                          sqlreader.Close();

                  }
                  catch (Exception ex)
                  {                          
                     MessageBox.Show(ex.ToString());            
                  }                                           
              }
private void button1_Click(object sender, EventArgs e)
        {
            if(listView1.Items.Count > 1)
            {
                listView1.Items.Clear();
            }
            var listMember = new List<string>{};
            var listOnline = new List<string>{};

            // SQL PART //

    using (conn)
    {
       conn.Open();
       ///...1st Query
       QueryTwoFields("SELECT fullname,online FROM member WHERE active = '1' ORDER BY online DESC",listmember,listonline)
        //...2nd query
        QueryTwoFields("your new Select Statement",myOtherList1,myOtherlist2)    
      ....
    }
}

EDIT : Take in mind you cant define QueryTwoFields method inside button handler. You must define it outside (see code above). Also Define your connection data in the start of the programm:

    namespace MyProject
    {
        /// <summary>
        /// Defiine your connectionstring and connection
        /// </summary>
        /// 

        public partial class Form1 : Form
        {  public static string connString = "Server=10*****;Port=3306;Database=e***;Uid=e***;password=********************;";              
           MySqlConnection  conn = new MySqlConnection(connString);

.........
C4d
  • 3,183
  • 4
  • 29
  • 50
apomene
  • 14,282
  • 9
  • 46
  • 72
  • Do I just have to change the query (command.CommandText = ...) at positions of '1st query' and '2nd query'? Could you provide a little bit more detail for this? When using 'using(conn)' I guess there is no need to open the connection manually right? Because it is handled by the 'using(conn)' itself? – C4d Sep 04 '14 at 07:56
  • 1
    Wow this looks pretty. Thanks for your effort for now. Give me some time to check this out. Ill mark it later if this works for me :). – C4d Sep 04 '14 at 08:09
  • Where do I have to put my connString (including server-data) and the MySqlConnection? Both, outside and inside the function gives me errors for "conn" could not be found. I could provide my new code if this is helpful. For now I put them both at the first position of the try{}. But then 'using(conn)' shows an error 'invalid token "using"'. – C4d Sep 04 '14 at 08:53
  • Then it tells me ( hopefuly correct translated) 'A fieldiniti. cannot be referenced on the non-static field, method or property "Form1.connString"'. I also posted my current code into the question. By the way: Shouldnt there be only one bracked after your 'sqlreader.Close();'? – C4d Sep 04 '14 at 09:11
  • 1
    Yes , typo..I removed the extra bracket also Don't declare method static ..see my edit – apomene Sep 04 '14 at 09:13
  • Wow. Thanks for taking so much time for details. I corrected everything. Quite all errors are gone. The last one (MysqlConnection conn = new MysqlConnection(connString) is still there as written in my last comment: 'A fieldiniti. cannot be referenced on the non-static field, method or property "Form1.connString"' – C4d Sep 04 '14 at 09:22
  • "public void QueryTwoFields(...)". So yes, I did. Just to be sure: My 'connString' and 'MySqlConnection conn' are bot at the first place inside the 'public partial class'. Ill edit my question to get a better overview. – C4d Sep 04 '14 at 09:27
  • The error for connString is gone. But there is an older one showing up again for "conn" inside the QueryTwoField and also for 'conn' inside the using-statement called: 'conn does not exist in the current context'. My latest code is updated in my question. – C4d Sep 04 '14 at 09:39
  • 1
    last edit I believe...Set it static in the beginning – apomene Sep 04 '14 at 09:44
  • Wasnt correct at all. The 'public static' has to be set for the first line 'string connString = ....'. I edited your post. Accept it so I can mark it as solved. Everything is running fine. In the end thanks again for your steady nerves. You helped me out a lot! – C4d Sep 04 '14 at 09:52
  • Very nice support provided for the gent – Drew Jan 05 '16 at 17:23
3

Datatables are fantastic

Using a data table is a nice way to do both read and write. And it comes with the luxury of eveything you can do with a datatable - like asssigning it directly to a datagrid control, sorting, selecting and deleting while disconnected.

The sample below assumes a MySqlConnection conection property managed by calls to your own OpenConnection() and CloseConnection() methods not shown.

Simple datatable read demo:

    public DataTable Select(string query = "")
    {
        //Typical sql: "SELECT * FROM motorparameter"


        DataTable dt = new DataTable();

        //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();

            dt.Load(dataReader);

            //close Data Reader
            dataReader.Close();

            //close Connection
            this.CloseConnection();

            //return data table
            return dt;
        }
        else
        {
            return dt;
        }
    }

In case of writing back the datatable to the database - supply the SQL you used in the read (or would have used to read to the data table):

    public void Save(DataTable dt, string DataTableSqlSelect)
    {
        //Typically "SELECT * FROM motorparameter"
        string query = DataTableSqlSelect;

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


            MySqlDataAdapter adapter = new MySqlDataAdapter(mySqlCmd);
            MySqlCommandBuilder myCB = new MySqlCommandBuilder(adapter);
            adapter.UpdateCommand = myCB.GetUpdateCommand();

            adapter.Update(dt);

            //close Connection
            this.CloseConnection();

        }
        else
        {
        }
    }

The neat thing the datatable is extremely flexible. You can run your own selects against the table once it contains data and before writing back you can set or reset what rows needs updating and by default the datatable keeps track of what rows you update in the table. Do not forget primary key column(s) for all tables in the db.

For multiple queries consider if possible using a join between the database tables or same table if data related or use a UNION sql syntax if column count and type of data is the same. You can allways "create" your extra column in the select to differ what data comes from what part of the UNION.

Also consider using CASE WHEN sql syntax to conditionally select data from different sources.

tofo
  • 388
  • 3
  • 8
  • Likewise too here for you tofo, thanks for showing the snippets – Drew Jan 05 '16 at 17:24
  • After more than one year I'm coming back to this. Finally I've got enough knowledge to get what happens in here. I havnt known about the `Load` function on the DataTable so far. Looks quite awesome. Even more awesome that there is a way to generate update-statements automatically. – C4d Jul 08 '16 at 10:31
  • Btw: I've extended `DataTable` to a custom `MysqlTable` thats saving the `SELECT` statement after getting the output. This way, I just have to pass my `MysqlTable` to the update-method and magic happens. :D. – C4d Jul 08 '16 at 10:32