SQL Server distinct connection to database in C# - c#

I am trying to drop down box in design but in database table category has duplicates. I tried to execute by using below code. But it is not executing. It just receiving all commands which I have been changes in properties:
cmd.CommandText = #"Select Distinct Category_Desc from
Database***name order
by Category_Desc";
adapter.SelectCommand = cmd;
SqlDataReader dr1 = cmd.ExecuteReader();
dr1.Read();
comboBoxCategory.ValueMember = "Category_Desc";
comboBoxCategory.DisplayMember = "Category_Desc";
comboBoxCategory.DataSource = dr1;
dr1.Dispose();
Can anyone please help how to execute distinct query from the code?

Data reader is a forward only cursor that you have to iterate and close after the last item.Look at this code segment
SqlDataReader dr1= command.ExecuteReader();
ArrayList arl= new ArrayList();
while (dr1.Read())
{
arl.Add(dr1("Category_Desc"));
}
dr1.close();
//If its a winform project use this
string [] str = al.ToArray(typeof(string));
FarPoint.Win.Spread.ComboBoxCellType cb = new
FarPoint.Win.Spread.ComboBoxCellType();
cb.Items = arl;

Use the adapter to fill a DataTable instead. You already have the adapter and it already has the SelectCommand assigned.
adapter.SelectCommand = cmd;
System.Data.DataTable dtCategories = new System.Data.DataTable();
adapter.Fill(dtCategories);
comboBoxCategory.ValueMember = "Category_Desc";
comboBoxCategory.DisplayMember = "Category_Desc";
comboBoxCategory.DataSource = dtCategories;

Related

Inserting selected items from a ListBox into MSSQL database with ADO.NET (c#)

I would like to know how to insert selected items from a ListBox into a MSSQL Database.
I am developing an ASP.NET web app and this is the problem:
I have a Listbox named lbxRuoli and items are loaded directly from the database:
SqlCommand cmd = new SqlCommand("select descrizione_Ruoli, id_Ruoli from Ruoli", conn);
SqlDataReader dr = cmd.ExecuteReader();
ListItem li = new ListItem("- SELEZIONA -", "");
lbxRuoli.Items.Add(li);
while (dr.Read())
{
li = new ListItem(dr["descrizione_Ruoli"].ToString(), dr["id_Ruoli"].ToString());
lbxRuoli.Items.Add(li);
}
dr.Close();
cmd.Dispose();
Now it comes to write the INSERT for the selected items:
for (int i = 0; i < lbxRuoli.Items.Count; i++)
{
if (lbxRuoli.Items[i].Selected == true)
{
cmd = new SqlCommand("insert into [Utenti.Ruoli] (id_Utenti, id_Ruoli) values(#id, #idR)", conn);
cmd.Parameters.AddWithValue("#id", txtId.Text);
cmd.Parameters.AddWithValue("#idR", lbxRuoli.SelectedValue);
cmd.ExecuteNonQuery();
}
}
It happens that I only insert the same first selected item for the total numbers of the selected items.
It would be wonderful if someone can help me!
Thanks to every one in advance!
Connections need to be not only closed but disposed to release unmanaged objects. using blocks handle this even if there is an error.
Commands also need to be disposed. To accomplish this they should be declared local to the method where they are used. using blocks will close and dispose you database objects.
You don't want to hold a connection open while you update the user interface. Fill a DataTable, close the connection (the using block does it) and then fill the ListBox from the DataTable.
To insert the data create the connection, command and fill the parameters collection outside the loop. Only the values of the parameters change inside the loop
The code below demonstrates how to use the .Add method for parameters. I had to guess at the type and size of the parameters. Check your database and adjust the code accordingly making sure that the parameter values are compatible with the SqlDbType.
private string ConStr = "Your connection string";
private DataTable GetListData()
{
DataTable dt = new DataTable();
using (SqlConnection cn = new SqlConnection(ConStr))
using (SqlCommand cmd = new SqlCommand("select descrizione_Ruoli, id_Ruoli from Ruoli", cn))
{
cn.Open();
dt.Load(cmd.ExecuteReader());
}
return dt;
}
private void FillListBox()
{
DataTable dt = GetListData();
ListItem li = new ListItem("- SELEZIONA -", "");
lbxRuoli.Items.Add(li);
foreach (DataRow row in dt.Rows)
{
li = new ListItem(row["descrizione_Ruoli"].ToString(), row["id_Ruoli"].ToString());
lbxRuoli.Items.Add(li);
}
}
private void InsertData()
{
using (SqlConnection cn = new SqlConnection(ConStr))
using (SqlCommand cmd = new SqlCommand("insert into [Utenti.Ruoli] (id_Utenti, id_Ruoli) values(#id, #idR)", cn))
{
cmd.Parameters.Add("#id", SqlDbType.VarChar, 20);
cmd.Parameters.Add("#idR", SqlDbType.VarChar, 20);
cn.Open();
foreach (ListItem li in lbxRuoli.Items)
{
if (li.Selected)
{
cmd.Parameters["#id"].Value = li.Text;
cmd.Parameters["idR"].Value = li.Value;
cmd.ExecuteNonQuery();
}
}
}
}

C# reading values from datatable filled with sql select

I am coding win form app, which checks on startup right of the currently logged user. I had these right saved in MS SQL server in the table. When importing data to Datatable, there is no problem. But when I want to read value, there is message "cannot find column xy".
SqlDataAdapter sdaRights = new SqlDataAdapter("SELECT * FROM rights WHERE [user]='" + System.Security.Principal.WindowsIdentity.GetCurrent().Name + "'", conn);
DataTable dtRights = new DataTable(); //this is creating a virtual table
sdaRights.Fill(dtRights);
Object cellValue = dt.Rows[0][1];
int value = Convert.ToInt32(cellValue);
MessageBox.Show(value.ToString());
I would like, that program would save the value from SQL to int.
You are assuming that you have rows being returned, would be my first guess. You should loop through your DataTable instead of simply trying to access element 0 in it.
DataTable dtRights = new DataTable();
sdaRights.Fill(dtRights);
foreach(DataRow row in dtRights.Rows) {
Object cellValue = row[1];
int value = Convert.ToInt32(cellValue);
MessageBox.Show(value.ToString());
}
using (SqlConnection con = new SqlConnection("your connection string"))
{
using (SqlCommand cmd = new SqlCommand("SELECT [column_you_want] FROM [rights] WHERE [user] = #user"))
{
cmd.Parameters.AddWithValue("#user", System.Security.Principal.WindowsIdentity.GetCurrent().Name);
con.Open();
int right = Convert.ToInt32(cmd.ExecuteScalar());
}
}

A chart element with the name 'John' already exists in the 'SeriesCollection'

I am following this post, to build a bar chart and show on my webpage. Below is the code i have done to accomplish it:
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "select * from ForChart";
cmd.CommandType = CommandType.Text;
SqlDataAdapter adp = new SqlDataAdapter();
adp.SelectCommand = cmd;
DataSet myDataSet = new DataSet();
adp.Fill(myDataSet, "Query");
foreach (DataRow row in myDataSet.Tables["Query"].Rows)
{
string seriesName = row["SalesRep"].ToString();
Chart1.Series.Add(seriesName);
Chart1.Series[seriesName].ChartType = SeriesChartType.Line;
Chart1.Series[seriesName].BorderWidth = 2;
for (int colIndex = 1; colIndex < myDataSet.Tables["Query"].Columns.Count; colIndex++)
{
string columnName = myDataSet.Tables["Query"].Columns[colIndex].ColumnName;
string YVal = Convert.ToString(row[columnName]);
Chart1.Series[seriesName].Points.AddXY(columnName, YVal);
}
}
GridView1.DataSource = myDataSet;
GridView1.DataBind();
cmd.Connection.Close();
And my table is having the below data. Please check the snapshot
But when i run the code i am getting the below error. Please help me to resolve the issue:
A chart element with the name 'John' already exists in the 'SeriesCollection'.
I am not able to traverse the records thats why i am getting this error, but i don't know how to traverse through all the records.
Coding help would be very much appreciated. Thanks.
I'm assuming that Chart1.Series requires unique names, and thus this call will fail when you try to enter the same name multiple times:
Chart1.Series.Add(seriesName);
Ugh, that entire example on MSDN is filled with bad practices:
select *
no usings used with SqlConnection, SqlCommand,...
mixing UI code and DB code (they should be in separate classes)
Look at this example for a possible solution.

Populate stored procedure result to a List<T>

Is there a way to map the results of a stored procedure to a generic list instead of a dataset/datatable?
Currently I follow these steps:
Execute stored procedure
Take the result in Dataset
Populate list from the Dataset.
Is there a way to eliminate step (2).
OleDbCommand cm = new OleDbCommand();
cm.Connection = AccessConnection();
cm.CommandType = CommandType.StoredProcedure;
cm.CommandText = "seltblContacts";
OleDbDataAdapter adp = new OleDbDataAdapter(cm);
DataTable dt = new DataTable();
adp.Fill(dt);
List<tblContacts> LstFile = new List<tblContacts>();
if (dt.Rows.Count > 0)
{
tblContacts t;
foreach (DataRow dr in dt.Rows)
{
t = PopulateContacts(dr);
LstFile.Add(t);
}
}
Yes of course you can do that - just execute your command and get back a reader, and then iterate over the rows in the result set and build up your objects:
using (OleDbCommand cm = new OleDbCommand())
{
cm.Connection = AccessConnection();
cm.CommandType = CommandType.StoredProcedure;
cm.CommandText = "seltblContacts";
List<tblContacts> LstFile = new List<tblContacts>();
using (OleDbReader reader = cm.ExecuteReader())
{
while(reader.Read())
{
tblContacts contact = new tblContacts();
// here, set the properties based on your columns from the database
contact.FirstName = reader.GetString(0);
contact.LastName = reader.GetString(1);
// etc.
LstFile.Add(contact);
}
reader.Close();
}
return LstFile;
}
For details on OleDbReader and how to use it, see this other SO question or find tons of tutorials and samples online using Bing or Google.

Drop down list not binding with sqldatareader

i have a form with a collection of about five drop down . i have my query as follows .
string sql = "SELECT a.clientID ,a.[cname],b.bid,b.[bname],c.contactID, c.[name] FROM "
+ " dbo.[CLIENT] AS a INNER JOIN dbo.[BRANCH] AS b "
+ "ON a.clientID = b.clientID JOIN dbo.[CONTACT] AS "
+ " c ON b.bid = c.bid ORDER BY a.clientID ";
i then followed and bind my drop down individually to their respective columns as follows.
SqlCommand cmd = new SqlCommand(sql, connection);
cmd.CommandType = CommandType.Text;
SqlDataReader reader = cmd.ExecuteReader();
drClient.Enabled = true;
drClient.DataSource = reader;
drClient.DataTextField = "cname";
drClient.DataValueField = "clientID";
drClient.DataBind();
drBranch.Enabled = true;
drBranch.DataSource = reader;
drBranch.DataTextField = "bname";
drBranch.DataValueField = "bid";
drBranch.DataBind();
drContact.Enabled = true;
drContact.DataSource = reader;
drContact.DataTextField = "name";
drContact.DataValueField = "contactID";
drContact.DataBind();
drEmail.Enabled = true;
drEmail.DataSource = reader;
drEmail.DataTextField = "name";
drEmail.DataValueField = "contactID";
drEmail.DataBind();
drFax.Enabled = true;
drFax.DataSource = reader;
drFax.DataValueField = "contactID";
drFax.DataTextField = "name";
drFax.DataBind();
when i run this, only the first drop down bind successfully. The rest don't. I also try to loop through the reader by adding
while(reader.read())
{
then my bindings
}
the above also fails. I though of looping as below as well.
while(read.HasRows)
{
}
it still fails. I am confused,any help would be appreciated. thanks
Reader is readonly and forward only that's why only first dropdonw get filled with data and others are empty.
You can use datset or Datatable for same problem .
SqlCommand cmd = new SqlCommand(sql, connection);
cmd.CommandType = CommandType.Text;
Dataset dsresult = cmd.ExecuteDataset();
If(dsResult !=null)
{
if(dsResult.Rows.count>0)
{
drClient.Enabled = true;
drClient.DataSource = dsResult.Tables[0] ;
drClient.DataTextField = Convert.ToString(ds.Tables[0].Columns["cname"]);
drClient.DataValueField = ds.Tables[0].Columns["clientID"] ;
drClient.DataBind();
}
}
Datareader is connected architecture needs continuous connection and fetches one row at a time in forward mode better use dataset which uses disconnected architecture and can be used for retrieving data multiple times.
This seems clear postback problem.
Bind your drop down on !postback.
Eg.
if(!IsPostBack)
{
populateDdl();
}
Either you will have to make a seperate reader for each binding
or you can do this by filling a datatable ( i would prefer this). Like,
DataTable dt = new DataTable();
using (SqlDataAdapter a = new SqlDataAdapter(sql, connection))
{
a.Fill(dt);
}
drClient.DataSource = dt;
drClient.DataBind();
drBranch.DataSource = dt;
drBranch.DataBind();
drContact.DataSource = dt;
drContact.DataBind();
drFax.DataSource = dt;
drFax.DataBind();
Your choices are to either rerun/refill it or create separate readers or better yet fill a datatable instead and then you can reuse the datatable.

Categories