Load Data from SQL Server into a combobox - c#

I tried to get data from SQL Server (2 tables: Famille and Compte) into 2 comboboxes in the Form_Load().
But as you see the result, it works with the 1st combobox, but the 2nd it shows System.Data.SqlClient.SqlDataReader
This is the Code
private void Tresorerie_Load(object sender, EventArgs e)
{
conn = new SqlConnection(connstring);
conn.Open();
String queryCompte = "select NomCom from Compte";
String queryFamille = "select NomFam from Famille";
commCompte = new SqlCommand(queryCompte, conn);
commFamille = new SqlCommand(queryFamille, conn);
try
{
//Compte
commCompte.CommandType = CommandType.Text;
dreaderCompte = commCompte.ExecuteReader();
while (dreaderCompte.Read())
{
queryCompte = dreaderCompte[0].ToString();
TreComBoxCompte.Items.Add(queryCompte);
}
}
catch (Exception)
{
MessageBox.Show("Problem with load Compte");
}
finally
{
dreaderCompte.Close();
}
try
{
//Famille
commFamille.CommandType = CommandType.Text;
dreaderFamille = commFamille.ExecuteReader();
while (dreaderFamille.Read())
{
queryFamille = dreaderFamille[0].ToString();
TreComBoxFamille.Items.Add(dreaderFamille);
}
}
catch (Exception)
{
MessageBox.Show("Problem with load Famille");
}
finally
{
dreaderFamille.Close();
}
conn.Close();
}

For second combobox you are adding your datareader dreaderFamille:
TreComBoxFamille.Items.Add(dreaderFamille);
while you should add queryFamille:
queryFamille = dreaderFamille[0].ToString();
TreComBoxFamille.Items.Add(queryFamille);
If you pay attention to item texts in your ComboBox you will guess the problem and when you look at code, you will see your guess is true.

for 2nd comboxbox, you are using wrong object to add
TreComBoxFamille.Items.Add(queryFamille);

You should do it like this:
while (dreaderFamille.Read())
{
queryFamille = dreaderFamille[0].ToString();
TreComBoxFamille.Items.Add(queryFamille);
}

Related

Iterating a table in SQL Server using datareader

I am iterating a incidentNoReserve tbl in SQL Server. On button click, if it matches a variable the entire row will be deleted from incidentNoReserve tbl.
This is the code:
private void button3_Click(object sender, EventArgs e)
{
try
{
using (var cmd106 = new SqlCommand("select * from [dbo].[incidentNoReserve]", cnn))
{
cnn.Open();
SqlDataReader reader = cmd106.ExecuteReader();
while (reader.Read())
{
var commonNo = reader["incidentNoReserveId"];
//Every new row will create a new dictionary that holds the columns
if (Convert.ToInt16(commonNo) == newLastIncidentNo )
{
var cmd107 = new SqlCommand("Delete from[dbo].[incidentNoReserve] where incidentNoReserveId = #newLastIncidentNo", cnn);
cmd107.Parameters.AddWithValue("#newLastIncidentNo", newLastIncidentNo);
cmd107.ExecuteNonQuery();
}
cnn.Close();
}
reader.Close();
}
}
catch (Exception ex)
{
// If an exception occurs, write it to the console
Console.WriteLine(ex.ToString());
}
finally
{
cnn.Close();
}
this.Close();
}
The newLastIncidentNo have 18 and while it reaches commonNo it have 10 which is only the first row in incidentNoReserve table.
What could be the problem?
You are closing the connection in the loop
And you are using the same connection to loop and update
it worked i have just removed the inner open and close connection.Thanks ALL
i fixed it like this :
while (reader.Read())
{
int commonNo = Convert.ToInt16(reader["incidentNoReserveId"]);
//Every new row will create a new dictionary that holds the columns
if (Convert.ToInt16(commonNo) == newLastIncidentNo)
{
reader.Close();
//newLastIncidentNo = (Convert.ToInt16(commonNo));
using (SqlCommand command = new SqlCommand("Delete from [dbo].[incidentNoReserve] where incidentNoReserveId = #newLastIncidentNo", cnn))
{
//MessageBox.Show(newLastIncidentNo.ToString());
command.Parameters.AddWithValue("#newLastIncidentNo", newLastIncidentNo);
command.ExecuteNonQuery();
}
}
}
cnn.Close();
}
}
catch (Exception ex)

Multiple CheckedListBox and database connections

I'm loading a table from a database into a CheckedListBox, and now I need to check which items are checked any time the user changes the check status of an item in the first CheckedListBox, and then add the corresponding parts of another table from my database to the second CheckedListBox.
So for example, I have chlbMeal and chlbFood. Inside the chlbMeal there are "Breakfast", "Dinner" and "Lunch". Now when the user selects any of these, I want the corresponding food options to show up in the chlbFood - for example, if "Breakfast" is checked, inside chlbFood we have "Fried eggs", "Eggs and Bacon", etc.
My project is somewhat different but that's the main the idea I want to achieve in this part of it. Here is my code:
private void chlbRadovi_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
if (chlbRadovi.CheckedItems.Count > 0)
{
int[] niz = new int[chlbRadovi.CheckedIndices.Count];
chlbRadovi.CheckedIndices.CopyTo(niz, 0);
foreach (int x in niz)
{
this.tipradovaTableAdapter1.Fill(this.ignaDataSet1.tipradova);
SqlConnection con = new SqlConnection(Konekcija.con);
SqlCommand cmd = new SqlCommand("select IDTR, Naziv from tipradova where IDRad in #IDRad", con);
cmd.Parameters.AddWithValue("#IDRad", chlbRadovi.ValueMember[x]);
SqlDataReader reader;
chlbTipoviRadova.DataSource = ignaDataSet1.tipradova;
chlbTipoviRadova.DisplayMember = "Naziv";
chlbTipoviRadova.ValueMember = "IDTR";
con.Open();
reader = cmd.ExecuteReader();
con.Close();
}
}
else
{
chlbTipoviRadova.DataSource = null;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
How can I do this?
Ok, here we go. First, bind data to your first CheckedListbox:
private string connectionString = "Your connection string";
private void cbListFirst_SetDataSource()
{
// Using block will automatically close connection when it's not used anymore
using (var con = new SqlConnection(connectionString))
{
SqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = #"SELECT Id, Name
FROM dbo.FoodTypes";
try
{
con.Open();
var foodTypes = new List<FoodType>();
using (SqlDataReader reader = cmd.ExecuteReader())
{
// Fill items for first CheckedListBox DataSource
while (reader.Read())
{
foodTypes.Add(new FoodType()
{
Id = (int)reader["Id"],
Name = reader["Name"] as string
});
}
}
// Set first CheckedListBox DataSource
cbListFirst.DataSource = foodTypes;
cbListFirst.DisplayMember = "Name";
cbListFirst.ValueMember = "Id";
}
catch (Exception ex)
{
// Clear DataSource and handle error (should be improved)
cbListFirst.DataSource = null;
MessageBox.Show("Error", ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
After you've done that, you should have ParentIds encapsulated inside your FoodType objects inside DataSource of your first CheckedListbox. Now, you shouldn't use SelectedIndexChanged event, but ItemCheck event instead. So every time user checks or unchecks one of the items event will be triggered. Only problem you have now is that inside this event, new CheckValue of clicked item is not yet applied, but it can be handled easy since we have information about new and old value inside EventArgs. Check this out:
private void cbListFirst_ItemCheck(object sender, ItemCheckEventArgs e)
{
// Clear second CheckedListbox DataSource
cbListSecond.DataSource = null;
var ingridients = new List<Ingridient>();
foreach (var item in cbListFirst.CheckedItems)
{
// If item was previously checked, we want to skip it because it's new value is
// unchecked and we shouldn't be adding it's child items to second CheckedListbox
if (cbListFirst.Items.IndexOf(item) != e.Index)
{
var foodType = (FoodType)item;
ingridients.AddRange(GetIngridientsForFoodType(foodType.Id));
}
}
// If item was previously unchecked, it's child items won't be caught in previous loop
// so we want to explicitly include them inside this if-block if new value is checked
if (e.NewValue == CheckState.Checked)
{
var foodType = (FoodType)cbListFirst.Items[e.Index];
ingridients.AddRange(GetIngridientsForFoodType(foodType.Id));
}
// Finally, bind new DataSource
cbListSecond.DataSource = ingridients;
cbListSecond.DisplayMember = "Name";
cbListSecond.ValueMember = "Id";
}
// This method returns list of Ingridients for single FoodType
private List<Ingridient> GetIngridientsForFoodType(int foodTypeId)
{
using (var con = new SqlConnection(connectionString))
{
SqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = #"SELECT Id, Name
FROM dbo.Ingridients
WHERE FoodTypeId = #FoodTypeId";
cmd.Parameters.AddWithValue("#FoodTypeId", foodTypeId);
try
{
con.Open();
var ingridients = new List<Ingridient>();
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
ingridients.Add(new Ingridient()
{
Id = (int)reader["Id"],
Name = reader["Name"] as string
});
}
}
return ingridients;
}
catch (Exception ex)
{
// Handle error (should be improved) and return null
MessageBox.Show("Error", ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
}
}
Now your second CheckedListbox should be filled with child values of items from first CheckedListbox.

Combobox not filling from database C#

I'm trying to fill a combo box on from load from a database, I'm getting the error "Invalid object name 'POOL'"
Form load event to populate dropdown on form load
private void FRMAddTeam_Load(object sender, EventArgs e)
{
if (CMBBXPool.Items.Count > 0)
CMBBXPool.Items.Clear();
Database.CLSDB DatabaseClass = new Database.CLSDB();
DatabaseClass.FillDropDownList();
}
This is the code in my database connection class
public void FillDropDownList()
{
string PoolName = "";
Team.FRMAddTeam TeamAdd = new Team.FRMAddTeam();
SqlConnection conn = GetConnection();
string selStmt = "SELECT [Name] FROM dbo.TBL_pool";
SqlCommand selCmd = new SqlCommand(selStmt, conn);
try
{
conn.Open();
SqlDataReader reader = selCmd.ExecuteReader();
while (reader.Read())
{
PoolName = reader["Name"].ToString();
TeamAdd.addPoolItem(PoolName);
}
}
catch (SqlException ex) { throw ex; }
finally { conn.Close(); }
return;
}
Code to add the pool name
public void addPoolItem(string PoolName)
{
CMBBXPool.Items.Add(PoolName);
}
Any help is much appreciated
Your code needs to be:
public void FillDropDownList(Team.FRMAddTeam TeamAdd)
{
string PoolName = "";
SqlConnection conn = GetConnection();
string selStmt = "SELECT [Name] FROM dbo.TBL_pool";
SqlCommand selCmd = new SqlCommand(selStmt, conn);
try
{
conn.Open();
SqlDataReader reader = selCmd.ExecuteReader();
while (reader.Read())
{
PoolName = reader["Name"].ToString();
TeamAdd.addPoolItem(PoolName);
}
}
catch (SqlException ex) { throw ex; }
finally { conn.Close(); }
return;
}
You call it from your form like this:
DatabaseClass.FillDropDownList(this);
This will work, however it is strongly advised to change the implementation of your database class and remove tight coupling with GUI.
It is WRONG to fill your GUI from database class - instead of that, you should return data from your database class and bind your data to GUI in the GUI class.
http://en.wikipedia.org/wiki/Loose_coupling
http://en.wikipedia.org/wiki/Object_orgy
http://en.wikipedia.org/wiki/Separation_of_concerns
Sounds like you dont have table Pool.Are you sure its there?
Log into your SQL management studio and use query analyzer to run the same command.
There could be many reasons for that If your schema is different or do you have permission to access that table ? or are you checking the right database ?
UPDATE:
You should try using SELECT [Name] FROM dbo.TBL_Pool

I don't want my datagridview to generate colums automatically

I have a winform app which works correctly but I want to choose the column names, so I created the new columns.
When I open the application now, I have the blank manually generated columns, and then the autogenerated columns containing the data.
so I did:
dataGridView1.AutoGenerateColumns = false;
(on Form1 load)
and then:
List<Movimenti> source = dbo.RecuperaMovimenti(contoSelezionato);
dataGridView1.DataSource = source;
but I get an error:
object reference not set to an instance of an object.
I post some code which should help you to locate the problem:
When I select an item from my listbox, I want the datagridview to load the data for the selected user:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
DboInfo dbo = new DboInfo();
try
{
contoSelezionato = listBox1.SelectedItem.ToString();
}
catch
{}
lblConto.Text = contoSelezionato;
lblConto.Visible = true;
lblTotale.Text = totale;
lblTotale.Visible = true;
try
{
List<Movimenti> source = dbo.RecuperaMovimenti(contoSelezionato);
dataGridView1.DataSource = source;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
dbo method for getting the data:
public List<Movimenti> RecuperaMovimenti(string contoSelezionato)
{
List<Movimenti> risultato = new List<Movimenti>();
SQLiteConnection m_dbConnection = new SQLiteConnection();
try
{
m_dbConnection = OpenConnection();
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
SQLiteDataReader rdr;
string sql = "SELECT id_movimento, data_movimento, descrizione_movimento, importo_movimento FROM movimenti WHERE nome_conto = '"+contoSelezionato+"'";
SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
rdr = command.ExecuteReader();
while (rdr.Read())
{
Movimenti MOV = new Movimenti();
MOV.id = (Int64)rdr["id_movimento"];
//MOV.nome_conto = (string)rdr["nome_conto"];
MOV.data = (string)rdr["data_movimento"];
MOV.descrizione = (string)rdr["descrizione_movimento"];
MOV.importo = Convert.ToInt32(rdr["importo_movimento"]);
risultato.Add(MOV);
}
rdr.Close();
m_dbConnection.Close();
return risultato;
}
edit:
that's a picture. My data doesn't go into my columns, it just creates auto generated columns
May be, I think errors exist here:
contoSelezionato = listBox1.SelectedItem.ToString();
Can't get value from listBox.
Or here:
while (rdr.Read())
{
Movimenti MOV = new Movimenti();
MOV.id = (Int64)rdr["id_movimento"];
//MOV.nome_conto = (string)rdr["nome_conto"];
MOV.data = (string)rdr["data_movimento"];
MOV.descrizione = (string)rdr["descrizione_movimento"];
MOV.importo = Convert.ToInt32(rdr["importo_movimento"]);
risultato.Add(MOV);
}
One or more item doesn't contain anything value.
This or change
col.DataPropertyName = "ID"
by
col.DataPropertyName = "id"
Movimenti class has "id" property, not "ID"

C# data reader does not retrieve the data

I am trying to load data into a textbox by using a DataReader depend on the Drop down list selection. Didn't get error from this code, but the data is not loaded into textbox. please correct me.
public void text()
{
cn1.Open();
string s;
s = "select Request_Type from component where Material_Code='" + Mcodeddl.SelectedItem.Text + "' ";
SqlCommand cd1 = new SqlCommand(s, cn1);
SqlDataReader rd;
try
{
rd = cd1.ExecuteReader();
while (rd.Read())
{
TextBox4.Text = rd["Request_Type"].ToString().Trim();
}
rd.Close();
}
catch (Exception e)
{
Response.Write(e.Message);
}
finally
{
cd1.Dispose();
cn1.Close();
}
}
public void MC()
{
Mcodeddl.Items.Clear();
ListItem li1 = new ListItem();
li1.Text = "-Select-";
Mcodeddl.Items.Add(li1);
Mcodeddl.SelectedIndex = 0;
cn1.Open();
string s1;
s1 = "select Material_Code from component";
SqlCommand cd1 = new SqlCommand(s1, cn1);
SqlDataReader dr1;
try
{
dr1 = cd1.ExecuteReader();
while (dr1.Read())
{
ListItem ni1 = new ListItem();
ni1.Text = dr1["Material_Code"].ToString().Trim();
Mcodeddl.Items.Add(ni1);
}
dr1.Close();
}
catch (Exception e)
{
Response.Write(e.Message);
}
finally
{
cd1.Dispose();
cn1.Close();
}
}
If everything works fine without exceptions that is mean the connection established correctly and the SQL command is correct. I think you have to make sure about your SQL statement. Maybe it returns nothing because there are no matches.
We need more explain about your issue.

Categories

Resources