I know it's been asked many times and there's so many resources about this but believe me i tried those, Unfortunately same thing is always happen. I really don't know why my combo box column value is repeating. Can someone help me in doing these in a proper way. Did i forgot something here ? Thank you
public void FillComboBox()
{
using (var con = SQLConnection.GetConnection())
{
using (var cmd = new SqlCommand("SELECT * FROM employee_product", con))
{
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
cbox_order.Items.Add("Code").ToString();
cbox_order.Items.Add("Model").ToString();
cbox_order.Items.Add("Itemdescription").ToString();
}
}
}
}
}
Here's the provided image
If you check the code, you are basically just adding the strings "Code", "Model" and "Itemdescription" to the combobox. I guess you want rather something like:
while (reader.Read())
{
cbox_order.Items.Add($"{reader["Code"]} {reader["Model"]} {reader["Itemdescription"]}");
}
In this snippet I am using the reader to get values of the columns in the returned row from the DB and then displaying joining those values in a single string that is then added to the ComboBox as an item.
Update
If you know the column names, why not just do this?
public void FillComboBox()
{
cbox_order.Items.Add("Code").ToString();
cbox_order.Items.Add("Model").ToString();
cbox_order.Items.Add("Itemdescription").ToString();
}
First load data into a DataTable:
var connection = #"Your connection string";
var command = "Your SELECT command text";
var table = new DataTable();
using (var adapter = new SqlDataAdapter(command, connection))
adapter.Fill(table);
To show list of columns in a ComboBox:
comboBox1.DataSource = table.Columns.Cast<DataColumn>().ToList();
comboBox1.ValueMember = "ColumnName";
comboBox1.DisplayMember = "ColumnName";
To show data in DataGridView:
dataGridView1.DataSource = table;
In above code I suppose you are going to show columns of the table which you also want to load its data at the same time. In case which you just want to load just column information, you can use:
adapter.FillSchema(table, SchemaType.Mapped);
actually your not using your DataReader but you just add Code, Model and ItemDescription item for each row found with the MySQL query.
cbox_order.Items.Add("Code").ToString();
cbox_order.Items.Add("Model").ToString();
cbox_order.Items.Add("Itemdescription").ToString();
If you want to use the result of the MySQL query you can try this instead:
cbox_order.Items.Add(reader["Code"].ToString()).ToString(); // Change "Code" by the column name into the database
cbox_order.Items.Add(reader["Model"].ToString()).ToString(); // Change "Model" by the column name into the database
cbox_order.Items.Add(reader["Itemdescription"].ToString()).ToString(); // Change "Itemdescription" by the column name into the database
Don't forget to close the reader at the end
reader.Close();
EDIT
if you want the column name instead of data you can use this query, but that's useless if you already know the column name.
SELECT COLUMN_NAME FROM information_schema.columns WHERE table_schema='databasename' AND table_name='tablename'
Try to close and dispose of reader and close the connection.
reader.close;
reader.dispose;
con.close();
Related
I want to store all records from a MySQL table column in an array (C#).
E.g. if there is the column "name" in a table:
name
other column
...
Peter
Marc
Henry
... I want to store these names as elements in an array/list programmatically. The goal is to be able to access each element (in this case name) itself and going on with that.
Using a MySqlDataReader didn't work out that good, because it only returned me the last record in the column:
conn.Open();
string getNameQuery = "SELECT * FROM myTable";
MySqlCommand getName = new MySqlCommand(getNameQuery, conn);
dataReader = getName.ExecuteReader();
while(dataReader.Read())
{
dataReader.getString("name");
}
conn.Close();
Create a List and add the values to it.
List<string> ls = new List<string>();
while(dataReader.Read())
{
ls.Add(dataReader.GetString("name"));
}
Also, as I suggested, if you need only name column then write the query SELECT name FROM myTable. There is no need to fetch other columns.
I'm populating a DGV with data from a database and everything works fine, with the exception of when 0 rows are returned to the DataTable that populates the DGV. And I'm not sure how exactly to handle that situation, which I do need to allow for due to the program requirements.
Here's the Form code that calls the data binding method:
public void PopulateDgvCategories()
{
string companyFilter = cboSelectCompany.Text;
string categoryFilter = cboSelectCategory.Text;
db categoriesData = new db();
if (categoryFilter == "All Categories")
{
string catsQuery = "SELECT id, category, old_value, old_desc, new_value, new_desc, reference1, reference2 " +
"FROM masterfiles.xref WHERE company_name = #company ORDER BY category, old_value";
this.dtCategories = categoriesData.GetDgvData(catsQuery, companyFilter, categoryFilter);
}
else
{
string catsQuery = "SELECT id, category, old_value, old_desc, new_value, new_desc, reference1, reference2 " +
"FROM masterfiles.xref WHERE company_name = #company and category = #category ORDER BY old_value";
this.dtCategories = categoriesData.GetDgvData(catsQuery, companyFilter, categoryFilter);
}
// Need to check this.dtCategories.Rows.Count
// If 0, then need to figure out how to handle that
dgvCategories.DataSource = this.dtCategories;
dgvCategories.Columns[0].Visible = false;
dgvCategories.Rows[0].Cells[0].Selected = false;
}
And here's how I'm retrieving the data and filling the DataTable:
public DataTable GetDgvData(string selectQuery, string companyFilter, string categoryFilter)
{
using (NpgsqlConnection conn = new NpgsqlConnection(connString))
using (NpgsqlCommand cmd = new NpgsqlCommand(selectQuery, conn))
{
cmd.Parameters.Add(new NpgsqlParameter("company", companyFilter));
if (categoryFilter != "All Categories") cmd.Parameters.Add(new NpgsqlParameter("category", categoryFilter));
DataSet ds = new DataSet();
conn.Open();
using (NpgsqlDataAdapter da = new NpgsqlDataAdapter(cmd))
{
da.Fill(ds);
}
conn.Close();
return ds.Tables[0];
}
}
It is possible for the categoryFilter variable to cause the query to return 0 rows.
What is the best way to handle that? I'm thinking manually create the DGV with just the header row (column names) and display a MessageBox saying no rows were returned. Is that possible/feasible and would it be the best way to handle that?
There is absolutely no problem binding a datatable with zero rows - it will have a set of columns of the correct types regardless and will autocreate columns if the AutoGenerateColumns property is true
The problems come simply because you're trying to access a datagridview cell at 0,0 without making sure it exists, so you could put:
dgvCategories.DataSource = this.dtCategories;
dgvCategories.Columns[0].Visible = false;
it(dtCategories.Rows.Count > 0)
dgvCategories.Rows[0].Cells[0].Selected = false;
But you should just take this line out completely - it doesn't do anything anyway; it doesn't hide the blue selection highlight in the top left and a freshly bound datagridview's top left cell is already Selected=false so you're not achieving anything other than an exception with this line of code
If you want to hide the blue selection highlight when a DGV isn't focused, set the cell's Style.SelectionBackColor to be the same as its Style.BackColor, but do set it to something visible when the user focuses the grid or they will struggle to understand why they can't make that cell highlighted.
If you want to remove the ghost row that allows you to add new values, set AllowUserToAddRows to false
If you want to let the user know there were no rows from a recent search, place a label on top of the DGV with a "Your search 'whatever' returned no results" and set its visibility depending on whether there are rows:
lblNoResults.Text = $"Your search '{categoryFilter}' returned no rows";
lblNoResults.Visible = dtCategories.Rows.Count == 0;
Finally, you don't need to use a DataSet when all you want is a DataTable. A datadapter can fill a datatable; there is no need to go to the extra wasted effort of using a dataset - it's like using a List<string> and accessing it's 0th element when all you want is a string. You also don't need to open/close the connection - dataadapter knows how to do this itself. It is intelligent enough to not close a connection opened elsewhere (in case there is a transaction in progress):
DataTable dt = new DataTale();
using (NpgsqlDataAdapter da = new NpgsqlDataAdapter(cmd))
{
da.Fill(dt);
}
return dt;
I am writing a small application in C# using windows forms. I have a combo box that I am populating by querying a database for column names to use as the values inside the combo box. My code currently can get the values just fine, however whenever I click on the combo box it removes any text and just displays a blank 'selected option'. I have tried multiple things to correct this (changed the database field from char to varchar), tried binding to a different dataset etc. but nothing has worked. Ive also looked at other posts on this such as
C# comboBox databinding - nothing happens, then it goes back to blank
Below is my code, and I believe I am doing the displaymember/valuemember part wrong however I do not understand what it is that is wrong. The column name in the database is Reason and it consists of 3 values.
Any help is appreciated.
String ConnString = ConfigurationManager.ConnectionStrings["Portal1"].ConnectionString;
SqlConnection conn = new SqlConnection(ConnString);
conn.Open();
SqlCommand sc = new SqlCommand("select [Reason] from tblReasons", conn);
SqlDataReader reader;
reader = sc.ExecuteReader();
DataTable dt = new DataTable();
dt.Columns.Add("Reason", typeof(string));
dt.Load(reader);
cboxReason.ValueMember = "Reason";
cboxReason.DisplayMember = "Reason";
cboxReason.DataSource = dt;
conn.Close();
Your code looks OK. I would not add the column, that should happen automatically. Here is my sample code that works:
SqlConnection conn = new SqlConnection(ConnString);
conn.Open();
var reader = new SqlCommand("select ID from Users", conn).ExecuteReader();
DataTable dt = new DataTable();
dt.Load(reader);
comboBox1.ValueMember = "ID";
comboBox1.DisplayMember = "ID";
comboBox1.DataSource = dt;
conn.Close();
Note: This populates with the list of values in the column. For the list of column names, I would suggest changing your query to return a list of columns for the table (DB specific query) OR look at the DataTable.Columns collection for the column names.
Did you try the answer from C# - Fill a combo box with a DataTable
cboxReason.BindingContext = this.BindingContext;
I've been working with a program where I import 2 excel files and those excel files have different columns names.. so it could be the possibility for a user to import the wrong excel file (with other column names) and my problem is that I'm reading the data from excel with OledbDataAdapter so I have to specified the name of each column, so when the user import the wrong file the program stop working (because the program can't find the right columns to get the data).
Okay so my question is, is there a way to check if a column exist in specific excel sheet?
So I'll be able to do something if the column doesn't exist in the file the user imported...
Here's a part of my code:
OleDbCommand command1 = new OleDbCommand(
#"SELECT DISTINCT serie FROM [Sheet1$]
WHERE serie =#MercEnInventario AND serie IS NOT NULL", connection);
command1.Parameters.Add(new OleDbParameter("MercEnInventario", MercInv));
string serieN = Convert.ToString(command1.ExecuteScalar());
readerOle = command1.ExecuteReader();
readerOle.Close();
I got an OleDbException when I try to give value to the string 'serieN' because the column name 'serie' doesn't exists in the excel file the user imported.
If you can help me I'll be so grateful :)
OleDbConnection has GetOleDbSchemaTable command that allows you to retrieve just the list of columns. An example code would be
DataTable myColumns = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, "Sheet1$", null });
This will return a DataTable, populated with column information (names, types and more). You can then loop thru Rows collection examining "COLUMN_NAME" column, something like
foreach (DataRow dtRow in myColumns.Rows)
{
if (dtRow["COLUMN_NAME"].ToString() == "serieN") // Do your stuff here ....
}
How about this:
public bool FieldExists(OleDbConnection connection, string tabName, string fieldName)
{
var adapter = new OleDbDataAdapter(string.Format("SELECT * FROM [{0}]", tabName), connection);
var ds = new DataSet();
adapter.Fill(ds, tabName);
foreach (var item in ds.Tables[tabName].Rows[0].ItemArray)
{
if (item.ToString() == fieldName)
return true;
}
return false;
}
I have created a MySQL table. I can insert Data but now I'd like to get the saved data after I enter it into another tab's TextBox in my Windows Application in c# language.
I have coded the button "Refresh" to get the data, but I dont know if its correct or not. Basically I want to click it, get the data from the table, and post it at the textbox.
Here is what I got so far for the getting data part:
private void button3_Click(object sender, EventArgs e)
{
string clanname, date, type, rules, final;
string connString = "Server=localhost;Database=request;Uid=root;Pwd=;";
using (MySqlConnection mcon = new MySqlConnection(connString))
using (MySqlCommand cmd = mcon.CreateCommand())
{
mcon.Open();
cmd.CommandText = "SELECT * FROM requesttcw";
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
clanname = textBox1.Text.Trim();
date = textBox2.Text.Trim();
type = textBox2.Text.Trim();
rules = textBox2.Text.Trim();
}
}
}
}
Please help!
Thanks
The Select query in your question is fetching data from your requesttcw table. You will want to read that data from your reader instance and add it to the appropriate text boxes. For instance, you could do something like this to get data:
//textBox1 will hold the value of the first row and first column of your database.
textBox1.Text = reader.GetString(0);
Updating the index in the GetString command above will change the column from which you are fetching data. So, you will have to update that index appropriately to fetch the proper data from your table and insert to the right text box's .Text property.
I don't know what type of data you are dealing with in your table. If the type is something other than string, you will want to use the appropriate Get function for the type, whether int, double, etc. Check out the MySqlDataReader reference page for more types.
Depending on the frequency of which your table layout changes, you may also want to use .GetOrdinal to get data using your reader. This command lets you specify a column name instead of its index. The above call could be changed to:
//assuming "clanname" is a column in your database
textBox1.Text = reader.GetString(reader.GetOrdinal("clanname");
Lastly, in your example you used
while (reader.Read()) { ... }
This will loop through each row in your query result set. I don't know how many text boxes you have or if you are looking for a specific format, but be aware that if you want to show data for a field from multiple rows in your text boxes, you will have to append to the Text property for each loop iteration.