I use ExecuteReader(). It returns only the last result. I wanted to display the result like an array in tbid_1.Text, tbid_1.Text, tbid_1.Text etc.

    public void Select(FrmVIRGO frm)
                {

                string query = "SELECT* FROM tb_patient_information ";
                if (this.OpenConnection() == true)
                { //Create Command
                    MySqlCommand cmd = new MySqlCommand(query, connection);
                    //Create a data reader and Execute the command


          MySqlDataReader dataReader = cmd.ExecuteReader();
                        while (dataReader.Read())
                        {

// I think use like this
                       frm.tbid_1.Text = dataReader["id_patient"][1].ToString(); //... id_patient1
                       frm.tbid_2.Text = dataReader["id_patient"][2].ToString(); //... id_patient2
                       frm.tbid_3.Text = dataReader["id_patient"][3].ToString(); //... id_patient3


                        }

                        //close Data Reader
                    dataReader.Close();

                    //close Connection
                    this.CloseConnection();
                    }
            }
有帮助吗?

解决方案

Your code appears to be expecting that once you've called dataReader.Read(), you can access all of the records by an index.

Your data reader is an instance of IDataReader, the interface that most .NET data access libraries use to represent the concept of "reading the results of a query". IDataReader only gives you access to one record at a time. Each time you call dataReader.Read(), the IDataReader advances to the next record. When it returns false, it means that you have reached the end of the result set.

For example, you could transform your code above to something like this:

        dataReader.Read();  // dataReader is at 1st record
        frm.tbid_1.Text = dataReader["id_patient"].ToString();

        dataReader.Read();  // dataReader is at 2nd record
        frm.tbid_2.Text = dataReader["id_patient"].ToString();

        dataReader.Read();  // dataReader is at 3rd record
        frm.tbid_3.Text = dataReader["id_patient"].ToString();

Note that this is not the way you should do it, I'm just using it to illustrate the way a DataReader works.

If you are expecting exactly 3 records to be returned, you could use something similar to the code above. I would modify it to verify that dataReader.Read() returns true before you read data from each record, however, and handle a case where it doesn't in a meaningful way (e.g., throw an exception that explains the error, log the error, etc.).

Generally though, if I am working with raw ADO.Net (as opposed to using an OR/M) I prefer to convert each record in the IDataReader to a dictionary beforehand, and work with those.

For example, you could write the following extension method for DataReader:

public static class DataReaderExtensions
{
    public static IList<IDictionary<string, object>> ListRecordsAsDictionaries(this IDataReader reader)
    {
        var list = new List<IDictionary<string, object>>();

        while (reader.Read())
        {
            var record = new Dictionary<string, object>();

            for (var i = 0; i < reader.FieldCount; i++)
            {
                var key = reader.GetName(i);
                var value = reader[i];
                record.Add(key, value);
            }

            list.Add(record);
        }

        return list;
    }
}

This method iterates over the IDataReader, and sticks the values from each row into a Dictionary<string, object>. I have found this pattern to generally be fairly useful when dealing with raw ADO stuff.

This approach has a couple of caveats:

  • You don't get access to the records (the Dictionary instances) until all of the data has been received from the server. If you are handling records individually as the DataReader makes them available, you may actually be able to start processing the data while some of it is still in-transit. (Note: This could be fixed by making this method return IEnumerable<IDictionary<string, object>> instead of IList<IDictionary<string, object>>, and using yield return to yield each record as it becomes available.)
  • If you are iterating over a large data set, you may not want to instantiate that many dictionaries. It may be better to just handle each record individually instead.
  • You lose access to some of the information that DataReader can provide about the record(s) (e.g., you can't use DataReader.GetDataTypeName as you are iterating over the records).
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top