How to iterate through a DataTable - c#

I need to iterate through a DataTable. I have an column there named ImagePath.
When I am using DataReader I do it this way:
SqlDataReader dr = null;
dr = cmd.ExecuteReader();
while (dr.Read())
{
TextBox1.Text = dr["ImagePath"].ToString();
}
How can I achieve the same thing using DataTable?

DataTable dt = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(dt);
foreach(DataRow row in dt.Rows)
{
TextBox1.Text = row["ImagePath"].ToString();
}
...assumes the connection is open and the command is set up properly. I also didn't check the syntax, but it should give you the idea.

foreach (DataRow row in myDataTable.Rows)
{
Console.WriteLine(row["ImagePath"]);
}
I am writing this from memory.
Hope this gives you enough hint to understand the object model.
DataTable -> DataRowCollection -> DataRow (which one can use & look for column contents for that row, either using columnName or ordinal).
-> = contains.

You can also use linq extensions for DataSets:
var imagePaths = dt.AsEnumerble().Select(r => r.Field<string>("ImagePath");
foreach(string imgPath in imagePaths)
{
TextBox1.Text = imgPath;
}

There are already nice solution has been given. The below code can help others to query over datatable and get the value of each row of the datatable for the ImagePath column.
for (int i = 0; i < dataTable.Rows.Count; i++)
{
var theUrl = dataTable.Rows[i]["ImagePath"].ToString();
}

The above examples are quite helpful. But, if we want to check if a particular row is having a particular value or not. If yes then delete and break and in case of no value found straight throw error. Below code works:
foreach (DataRow row in dtData.Rows)
{
if (row["Column_name"].ToString() == txtBox.Text)
{
// Getting the sequence number from the textbox.
string strName1 = txtRowDeletion.Text;
// Creating the SqlCommand object to access the stored procedure
// used to get the data for the grid.
string strDeleteData = "Sp_name";
SqlCommand cmdDeleteData = new SqlCommand(strDeleteData, conn);
cmdDeleteData.CommandType = System.Data.CommandType.StoredProcedure;
// Running the query.
conn.Open();
cmdDeleteData.ExecuteNonQuery();
conn.Close();
GetData();
dtData = (DataTable)Session["GetData"];
BindGrid(dtData);
lblMsgForDeletion.Text = "The row successfully deleted !!" + txtRowDeletion.Text;
txtRowDeletion.Text = "";
break;
}
else
{
lblMsgForDeletion.Text = "The row is not present ";
}
}

foreach(DataGridViewRow row in dataGridView1){ var a = row.Cells[4].Value.ToString(); }

Related

Read and Generate New Enumber

Hi i am new here i just want to ask question for this code.
i am making a condition on my new buttom that generate Enumber= Employee Number.
i have database but no data record yet. if i press my new buttom my sql statement will select he last record on my data but i don't have yet data so i am trying to make a condition.
if Enumber is empty in database it should return and give the new Enumber on my textbox = txtEnumber.Text = "100000".
i hope you understand my problem.
con.Open();
cmd = new SqlCommand("SELECT TOP 1 Enumber FROM Employee ORDER BY Enumber DESC ", con);
dr = cmd.ExecuteReader();
dr.Read();
if (dr["Enumber"] == null) // Error: "Invalid attempt to read when no data is present."
{
txtEnumber.Text = "100000";
return;
}
else
{
String a = dr["Enumber"].ToString();
txtEnumber.Text = ("");
for (int i = 0; i < 1; i++)
{
string val = a.Substring(1, a.Length - 1);
int newnumber = Convert.ToInt32(val) + 1;
a = newnumber.ToString("100000");
}
txtEnumber.Text = a;
}
con.Close();
Since you don't have any row in your case, you can't iterate your reader. Instead of that, you can use ExecuteScalar which returns null as an object if there is no data in first column of the first row since your query returns as SELECT TOP 1...
var result = cmd.ExecuteScalar();
if(result == null)
{
txtEnumber.Text = "100000";
}
You should check whether there are rows first. dr.Read() returns whether the DataReader has rows, use it.
Your DataReader returns no results...
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read()) {
// read data for first record here
}
If you have more than one result, use a 'while' loop.
while (dr.Read()) {
// read data for each record here
}
You should use dr.HasRows to check whether there is data or not.
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read()) {
dataTable.Load(dr);
}
If you have more than one result, use a 'foreach' loop.
foreach (DataRow Drow in datatable.Rows)
{
// read data for each record here
}
Try This is Worked..

How to retrieve data from database to CheckedListBox and set the items as checked?

I am new in WPF. I am trying to load the values from database to fill in CheckedListBox. Based on a condition, some items must be set to checked while loading in checkedlistbox.
How to do this? I have tried the code below, items are loaded in CheckedListBox, but are not checked.
Below is values loaded to checked listbox
public void fillcheck()
{
con = new SqlConnection(connectionstring);
con.Open();
string comboquery = "SELECT [Machine] FROM Department Where active='True'";
SqlCommand cmd = new SqlCommand(comboquery, con);
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
string fil1 = rdr.GetString(0);
Checkedlistbox1.Items.Add(fil1);
}
rdr.Close();
}
int departmentID=60//for just refer
Object[] jobs = CheckedlistBox1.Items.Cast<Object>().ToArray();
foreach (Object obj in jobs)
{
string query = "SELECT [Machine] FROM Department Where ID='" + departmentID+ "'";
SqlCommand cmd = new SqlCommand(query, con);
SqlDataReader rdr = cmd.ExecuteReader();
while(rdr.Read())
{
string mac = rdr.GetString(0);//Here i get two values(XRAY,CT)but finally shown CT only be checked,so how to do both checked
if (mac == obj.ToString())
{
int indexx = CheckedlistBox1.Items.IndexOf(mac);
if (indexx >= 0)
{
CheckedlistBox1.SetItemChecked(indexx, true);
}
}
}
rdr.Close();
}
You need to transfer your SqlDataReader rdr content to a DataTable. That will help you get a DataTable object containing multiple rows like you have mentioned.
Now for the next step, you can apply a foreach on that DataTable object to iterate over all its rows like this :
foreach(DataRow dr in dt.Rows)
{
if(yourCondition)
{
//set isChecked = true for the checkbox.
}
}
UPDATE :
Try modifying your while loop like this :
while (rdr.Read())
{
string mac = rdr.GetString(0);
ListItem li = new ListItem();
li.Value = "yourBindedValue";// some value from database column
li.Text = "yourBindedText";// use mac if its text.
int index = Checkedlistbox1.Items.IndexOf(li);
if (index >= 0)
{
Checkedlistbox1.SetItemChecked(index, true);
}
}
I have tested this and it works. You just have to pass the Text and Value of the CheckBoxListItem that you are trying to find in the li object and you can get the index if it exists. Make sure you pass both the attributes.
You should have used code-
foreach (int indexChecked in chlstBox.Items)
instead of
foreach (int indexChecked in chlstBox.CheckedIndices)
At start you have 0 selected items and thats why your outer for loop is not working..
EDIT-
Basic Logic is also incorrect.
You should loop through dataset, find the string in checkboxlist and then check it. So, outer foreach loop is not required. Also, make sure that you are using correct checkboxlist variable. In for loop you are using chlstBox
and while searching you are using Checkedlistbox1 ....

Get Values from DataTable by row and column name

I'm typically used to traditional table in SQL where I have multiple columns with rows populated. I execute a stored procedure and store all the data in DataTable and loop through the table to get the results I need. For example,
public static DataTable getInfo (string sessionID)
{
try
{
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["SandBox"].ConnectionString);
SqlCommand cmd = new SqlCommand("GetSessionInfo", conn);
cmd.Parameters.AddWithValue("SessionGUID", sessionID);
cmd.CommandType = CommandType.StoredProcedure;
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
return dt;
}
catch (Exception)
{
throw;
}
}
I would load the DataTable:
DataTable infoTbl = new DataTable();
infoTbl = getInfo(lbldatabasesessionID.Text);
And I would use foreach loop to loop through the DataTable.
foreach (DataRow row in infoTbl.Rows)
{
string x = col.ToString();
}
The issue I run into is the database guy gave me a stored procedure that returns a different output (different from what I'm used to). It's a row based.
The only way I can access for example the First Name is if I hard code the position like:
string firstName = infoTbl.Rows[16][2].ToString();
I don't feel comfortable doing this since the position could potentially change. How would I access ElementValue by knowing the name knowing ElementType and ElementName?
Any suggestions?
Using DataSet:
string firstName = string.Empty;
DataRow row = table.Select("ElementType = 'Demographics' AND ElementName = 'FirstName'").FirstOrDefault();
if (row != null)
{
firstName = (string)row["ElementValue"];
}
Using Linq:
string firstName = table.AsEnumerable()
.Where(f => f.Field<string>("ElementType") == "Demographics" &&
f.Field<string>("ElementName") == "FirstName")
.Select(f => f.Field<string>("ElementValue")).FirstOrDefault();

Binding ComboBox to DataTable (WinForms c#)?

I have a method which populates my ComboBox from a DataTable:
public string populateCompanyTransSellingEntityLookUp(ref System.Windows.Forms.ComboBox Combo, string Id, Contract Contract)
{
SqlCommand _comm = new SqlCommand();
_comm.Parameters.AddWithValue("#id", Id);
_comm.CommandText = "SELECT [name] FROM dbo.fnGetList(#id) ORDER BY [name]; ";
_comm.Connection = _conn;
_comm.CommandTimeout = _command_timeout;
DataTable dt = new DataTable();
try
{
SqlDataReader myReader = _comm.ExecuteReader();
dt.Load(myReader);
Combo.DataSource = dt;
Combo.DisplayMember = "name";
foreach (DataRow dr in dt.Rows)
{
if (dr["name"].ToString() == Contract.Company_Name.ToString())
{
Combo.Text = dr["company_int_name"].ToString();
}
}
}
catch
{
MessageBox.Show("Unable to populate Company Name LookUp");
}
return "";
}
I'm passing my saved value Contract.Company_Name into the forEach loop to find my required SelectedItem from the DataTable. The ComboBox is populated with my DataTable values from Combo.Datasource =dt; but my selected item isn't being set. The code compiles without exception. If I remove Datasource = dt;, theSelectedItemis set no problem. Why is theDatasourceoverriding mySelectedItem` and is there something I've missed with my binding?
Thanks all
At first you have to set the valueMember for sure. Then you can set the selectedValue Property instead of SelectedItem. The Item is one datasource record. So in your case it would be SelectedItem = dr! But iam not sure this is working.
Try this:
Combo.SelectedItem = dr;
I would suggest to use SelectedValue, then you don't need to loop through values "manually".
Also you don't need to use "heavy-weight" DataTable where you need just a collection of string values.
private IEnumerable<string> LoadNames(string id)
{
var query = "SELECT [name] FROM dbo.fnGetList(#id) ORDER BY [name]";
using (var connection = new SqlConnection("connectionString")
using (var command = new SqlCommand(query, connection)
{
// 36 is the size of the VarChar column in database(use your value)
command.Parameters.Add("#id", SqlDbType.VarChar, 36).Value = id;
connection.Open();
using (var reader = command.ExecuteReader())
{
var names = new List<string>();
while(reader.Read())
{
names.Add(reader.GetString(0));
}
return names;
}
}
}
public void Populate(ComboBox combobox, string id, Contract contract)
{
combobox.DataSource = LoadNames(id);
combobox.SelectedValue = contract.Copmpany_Name.ToString();
}
Few things to notice:
Dispose all objects which dealing with external resources (SqlConnection, SqlCommand and SqlDataReader)
Create SqlParameter with precise information about the type, for strings is important to provide size of the column in database. This information will improve SQL query performance on server side.
Don't pass combobox as a reference, populate method does not create new instance but only consume the given ComboBox instance.
Thank you for the help, I edited the code given that my problem was much more trivial.
public string populate_comboBox(ref System.Windows.Forms.ComboBox Combo)
{
SqlCommand _comm = new SqlCommand();
//edited for a simple one column sql query
_comm.CommandText ="SELECT [Column] FROM dbo.SQL_Table ORDER BY [Column];";
//MUST open sql connection to DB
SqlConnection conn = new SqlConnection(global_DB_String_Connection);
conn.Open();
_comm.Connection = conn;
DataTable dt = new DataTable();
try
{
SqlDataReader myReader = _comm.ExecuteReader();
dt.Load(myReader);
Combo.DataSource = dt;
Combo.DisplayMember = "ColumnName";
foreach (DataRow dr in dt.Rows)
{
//populates the combo box with query results
Combo.Text = dr["ColumnName"].ToString();
}
}
catch
{
Console.WriteLine("ComboBox Populate method has failed! ");
}
conn.Close();
return "";
}

List all data in sql table, row by row

I am trying to list all data in a table, but it only returns the first row, it doesn't loop the whole table.
i need to return the data as strings, because I will use it in a ASMX web service.
And the xml schema only returns the first row
<String> data in row 1<String>
i want it to return somthing like this:
<String> data in row 1<String>
<String> data in row 2<String>
<String> data in row 3<String>
and row 1 to n rows....
I have tested the sql statment in VS2012 query builder and there it works fine.
so i need to list out all the data in a way.
Here is my Code
public String finAllCompaniesForSpesficuserByUserId(String userid)
{
List<String> l = new List<String>();
try
{
String sql = "SELECT Companies.Name FROM UsersInCompanies INNER JOIN Companies ON UsersInCompanies.CompanyId = Companies.CompanyId WHERE UsersInCompanies.UserId ='" + userid + "'";
con = new SqlConnection(cs);
cmd = new SqlCommand(sql, con);
DataTable table = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(table);
con.Open();
dr = cmd.ExecuteReader();
dr.Read();
//while (dr.Read())
//{
// l.Add(dr["Name"].ToString());
//}
foreach (DataRow row in table.Rows)
{
return row["Name"].ToString();
}
}
finally
{
if (con != null)
con.Close();
}
/*
foreach (string p in l)
{
return p;
}
*/
return null;
}
Can someone point me in the right direction or give me an examples?
foreach (DataRow row in table.Rows)
{
return row["Name"].ToString();
}
you are returning from very first iteration itself.
Instead of returning immediately in the for-loop either use a yield statement (and change the return type to IEnumerable<String> - which just moves the for loop out of the function and somewhere else) or use a StringBuilder to build the resulting string.
StringBuilder sb = new StringBuilder(table.Rows.Count * 30); /* 30 is arbitrary */
foreach (DataRow row in table.Rows)
{
// yes 3 separate calls are correct
sb.Append("<String>");
sb.Append(row["Name"].ToString())
sb.Append("</String>\n");
}
/* after closing, cleaning up */
return sb.ToString();
Try this
var temp= "<String>" +
string.Join("</String>\n<String>", dt.Rows.Cast<DataRow>().Select(x => x["Name"].ToString())) +
"</String>";

Categories