After trying many solutions listed on the internet I am very confused now. I have a C#/SQL web application for which I am simply trying to bind an ExecuteReader command to a Dropdownlist so the user can select a value. This is a VS2008 project on an XP OS.
How it works is after the user selects a table, I use this selection as an input parameter to a method from my Datamatch.aspx.cs file. Then this Datamatch.aspx.cs file calls a method from my ADONET.cs class file. Finally this method executes a SQL procedure to return the list of columns from that table. (These are all tables in Adventureworks DB). I know that this method returns successfully the list of columns if I execute this SP in SSMS. However, I'm not sure how to tell if it works in VS or not.
This should be simple. How can I do this? Here is some of my code. The T-sQL stored proc:
CREATE PROCEDURE [dbo].[getColumnNames]
#TableName VarChar(50) AS
BEGIN
SET NOCOUNT ON;
SELECT col.name 'COLUMN_NAME' FROM sysobjects obj
INNER JOIN syscolumns col ON obj.id = col.id
WHERE obj.name = #TableName
END
It gives me desired output when I execute following from SSMS: exec getColumnNames 'AddressType'
And the code from Datamatch.aspx.cs file currently is:
private void CreateDropDownLists()
{
SqlDataReader dr2 = ADONET_methods.DisplayTableColumns(targettable);
int NumControls = targettable.Length;
DropDownList ddl = new DropDownList();
DataTable dt = new DataTable();
dt.Load(dr2);
ddl.DataValueField = "id";
ddl.DataTextField = "text";
ddl.DataSource = dt;
ddl.DataBind();
for (int counter = 0; counter < NumberOfControls; counter++)
{
ddl.ID = "DropDownListID " + (counter + 1).ToString();
btnSubmit.Style.Add("top", "auto");
btnSubmit.Style.Add("left", "auto");
btnSubmit.Style.Add("position", "absolute");
if (counter < 7)
{
ddl.Style["top"] = 100 * counter + 80 + "px";
ddl.Style["left"] = 250 + "px";
int bSubmitPosition = NumberOfControls * 100 + 80;
btnSubmit.Style.Add("top", System.Convert.ToString(bSubmitPosition) + "px");
}
else if (counter >= 7)
{
ddl.Style["top"] = 100 * counter - 620 + "px";
ddl.Style["left"] = 550 + "px";
int bSubmitPosition = NumberOfControls * 100 - 620;
btnSubmit.Style.Add("top", System.Convert.ToString(bSubmitPosition) + "px");
}
ddl.SelectedIndexChanged += new EventHandler(SelectedIndexChanged);
ddl_ht.Add(counter, ddl.SelectedValue);
pnlDisplayData.Controls.Add(ddl);
pnlDisplayData.Controls.Add(new LiteralControl("<br><br><br>"));
pnlDisplayData.Visible = true;
pnlDisplayData.FindControl(ddl.ID);
// dr.Close();
}
}
private void CreateLabels()
{
for (int counter = 0; counter < NumberOfControls; counter++)
{
Label lbl = new Label();
lbl.ID = "Label" + counter.ToString();
lbl.Text = headers[counter];
lbl.Style["position"] = "absolute";
if (counter < 7)
{
lbl.Style["top"] = 100 * counter + 50 + "px";
lbl.Style["left"] = 250 + "px";
}
else if (counter >= 7)
{
lbl.Style["top"] = (100 * counter) - 650 + "px";
lbl.Style["left"] = 550 + "px";
}
pnlDisplayData.Controls.Add(lbl);
pnlDisplayData.Controls.Add(new LiteralControl("<br><br><br>"));
}
}
Where ADONET_methods.DisplayTableColumns(targettable) is:
public static SqlDataReader DisplayTableColumns(string tt)
{
SqlDataReader dr = null;
string TableName = tt;
string connString = "Server=(local);Database=AdventureWorks;Integrated Security = SSPI";
string errorMsg;
SqlConnection conn2 = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand("getColumnNames"); //conn2.CreateCommand();
try
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = conn2;
SqlParameter parm = new SqlParameter("#TableName", SqlDbType.VarChar);
parm.Value = "Person." + TableName.Trim();
parm.Direction = ParameterDirection.Input;
cmd.Parameters.Add(parm);
conn2.Open();
dr = cmd.ExecuteReader();
}
catch (Exception ex)
{
errorMsg = ex.Message;
}
return dr;
}
The CreateLabels method above correctly shows me the labels. But the CreateDropDownLists method just shows me one dropdownlist with nothing in it. In other words, it is not selectable.
So how can I verify that the datareader is returning all 4 columns and inspect their values? I was able to find from datareader "COLUMN_NAME" but I don't know what properties to search to verify the column names.
It doesn't look like you're actually binding the dropdown anywhere in this code. You need to do something like this:
ddl.DataTextField = "COLUMN_NAME";
ddl.DataValueField = "COLUMN_NAME";
ddl.DataSource = dr.ExecuteReader();
ddl.DataBind();
Alternately, you can do this all in your page markup by using a SqlDataSource control.
<asp:SqlDataSource
id="SqlDataSource1"
runat="server"
DataSourceMode="DataSet"
ConnectionString="myConnString"
SelectCommand="myStoredProcedure"
>
</asp:SqlDataSource>
<asp:MyDropDownList id="ddl" runat="server" DataSource="SqlDataSource1"
DataTextField="COLUMN_NAME" DataValueField="COLUMN_NAME" />
In the ADONET_methods.DisplayTableColumns(targettable) method before returning dr, check if you get some value for dr.GetValue() using a breakpoint
string temp;
while(dr.Read())
{
temp = dr.GetValue(); //use a breakpoint here
}
Also instead of using dataReader and loading it to dataTable, you can better use a dataAdapter to fill the dataTable directly
public static DataTable DisplayTableColumns(string tt)
{
Datatable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter();
try
{
da.Fill(dt);
}
catch (Exception ex)
{
errorMsg = ex.Message;
}
string temp;
foreach(DataRow row in dt.Rows)
{
foreach(DataColumn column in dt.Columns)
{
temp = (row[column]); // use your breakpoint here
}
}
return dt;
}
Related
I have a dynamic query where I get the values from a list. I execute the query in foreach loop. I need to update the gridview accordingly like appending the rows. How can this be achieved
I have tried the below:-
foreach (string id in arr)
{
StringBuilder sb = new StringBuilder("select(select name from table1 where id =");
sb.Append("" + id + ")");
sb.AppendLine("as Component_Name,c.[name] as Scenario_Name, a.[processid] as Component from [action] a inner join [teststep] b on a.[stepid] = b.[stepid] inner join [process] c on b.[ProcessID] = c.[ProcessID] where a.CertifySequence = 0 and a.[processid] = ");
sb.Append("" + id + "");
SqlCommand command1 = new SqlCommand(sb.ToString(), connection);
try
{
using (SqlDataAdapter sda = new SqlDataAdapter(command1))
{
DataSet ds = new DataSet();
sda.Fill(ds);
int rowCount = GridView1.Rows.Count;
GridView1.DataSource = ds;
GridView1.DataBind();
rowCount = GridView1.Rows.Count;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
I cannot see gridview on my webpage. where am I going wrong
Using OleDbDataAdapter SQL query to search for secific entry in access database.
OleDbDataAdapter adapter1 = new OleDbDataAdapter(#"SELECT Gallery_Number FROM Paintings WHERE Painting Number = '" + searchString + "'", myDB);
searchString = Convert.ToString( adapter);
searchString returns System.Data.OleDb.OleDbDataAdapter and not a Gallery number.
I would like to know how to get the value of this adapter and put it into a textbox.
First of all, I'd use a Scalar for this, since you only return a single value.
OleDbCommand command = new OleDbCommand(queryString, connection);
command.Connection.Open();
int galeryNumber = (int)command.ExecuteScalar();
But let's take a look at your code:
DataSet galNum = new DataSet();
oledbAdapter.Fill(galNum);
int galeryNumber = int.Parse(ds.Tables[0].Rows[0].ItemArray[0].ToString());
The best way to gain access to a OleDbDataAdapter is by converting the result set into a `DataSet. Then you can iterate through this set.
for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
DataRow dr = ds.Tables[0].Rows[i]; //One result line in your set
//DataRow contains n columns
for (int i = 0; i < ds.Tables[0].Columns.Count; i++)
{
string someEntry = dr[i].ToString();
}
}
I want to Change Quantity value within Datagridview, it will change price also. how it is possible? which event is for it using C# windows form.CellEndEdit already used by other cell(productname).
private void dataGridViewSalesForm_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
try
{
string MatchingProduct = dataGridViewSalesForm.Rows[0].Cells[1].Value.ToString();
for (int i = 0; i < objArrayList.Count; i++)
{
if (objArrayList[i].ToString().ToLower().StartsWith(MatchingProduct.ToLower()))
{
dataGridViewSalesForm.Rows[0].Cells[1].Value = objArrayList[i].ToString();
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
/*connection for loading brandname from brandtable*/
string get_strProductName = dataGridViewSalesForm.Rows[0].Cells[1].Value.ToString();
string quantity = "1";
SqlConnection conn = new SqlConnection(connstr);
try
{
conn.Open();
string qry = "SELECT T_Inv_Brands.brand_name FROM T_Inv_Products INNER JOIN T_Inv_Brands ON T_Inv_Products.brand_id = T_Inv_Brands.brand_id WHERE T_Inv_Products.prod_name ='" + get_strProductName + "'";
SqlCommand cmd = new SqlCommand(qry, conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
dataGridViewSalesForm.Rows[0].Cells[2].Value = ds.Tables[0].Rows[0]["brand_name"].ToString();
dataGridViewSalesForm.Rows[0].Cells[3].Value = quantity;
conn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
/*connection for loading retailprice from producttable*/
SqlConnection connection = new SqlConnection(connstr);
try
{
conn.Open();
string qry = "SELECT retailprice FROM T_Inv_Products WHERE prod_name = '" + get_strProductName + "'";
SqlCommand cmd = new SqlCommand(qry, connection);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
dataGridViewSalesForm.Rows[0].Cells[4].Value = Convert.ToDouble(dt.Rows[0]["retailprice"].ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
//double quantityload = Convert.ToDouble(dataGridViewSalesForm.Rows[0].Cells[3].Value.ToString());
//double pricefetch = Convert.ToDouble(dataGridViewSalesForm.Rows[0].Cells[4].Value.ToString());
//double result = quantityload * pricefetch;
//dataGridViewSalesForm.Rows[0].Cells[4].Value = result.ToString();
}
You seem to think that you can use an event for one cell or column only. Instead you need to code your events in such a way that all necessary cells and/or columns get their own piece of logic.
It helps to partition your code into smaller pieces with helpful names that document the logic they contain!
Here is an example with two branches, one for a certain cell and one for a certain column. I pass out the DataGridViewCellEventArgs so the functions can access the DataGridView DGV just as the real event can.. Of course you can expand on it as needed:
int quantityColumnIndex = 3; // use your own numbers..
int currencyColumnIndex = 1; // ..and names!!
int currencyRowIndex = 0;
int pricePerUnitColumnIndex = 7;
int totalPriceColumnIndex = 8;
int totalBasePriceColumnIndex = 4;
private void DGV_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == quantityColumnIndex) doPriceCalc(e);
else if (e.ColumnIndex == currencyColumnIndex && e.RowIndex == currencyRowIndex)
doAllCalc(e);
}
void doPriceCalc(DataGridViewCellEventArgs e)
{
// 1st example
DGV[totalPriceColumnIndex, e.RowIndex].Value =
(int)DGV[quantityColumnIndex, e.RowIndex].Value *
(decimal)DGV[pricePerUnitColumnIndex, e.RowIndex].Value;
}
void doAllCalc(DataGridViewCellEventArgs e)
{
// 2nd example
decimal currency = (decimal) DGV[currencyColumnIndex,currencyRowIndex ].Value;
for (int row = 0; row < DGV.Rows.Count; row++)
DGV[pricePerUnitColumnIndex, e.RowIndex].Value =
(decimal)DGV[totalBasePriceColumnIndex, e.RowIndex].Value * currency;
}
Note that I have indexed the columns by their indeices. You may just as well index them by their names, e.g.: DGV[ "PricePerUnit", e.rowIndex]
I have a sample database like below, and I want to display only the red colored records in the datagrid. I have a condition for how to make those two cells red.
Sample Database
For example, I want to display records whose is value less than 10 in the book number column.
I used code like below for making them red.
Code
private void UpdateDataGridViewColor()
{
if (calledMethod == 2)
{
for (int i = 0; i < dataGridView1.RowCount; i++)
{
int j = 6;
DataGridViewCellStyle CellStyle = new DataGridViewCellStyle();
CellStyle.ForeColor = Color.Red;
if (isLate(dataGridView1[j, i].Value.ToString()))
{
dataGridView1[j, i].Style = CellStyle;
}
}
}
}
I used code something like the following.
Code
private void issueDetails()
{
calledMethod = 2;
string connectionPath = #"Data Source=Data\libraryData.dat;Version=3;New=False;Compress=True";
using (SQLiteConnection connection = new SQLiteConnection(connectionPath))
{
SQLiteCommand command = connection.CreateCommand();
connection.Open();
string query = "SELECT bookno as 'Book No.',studentId as 'Student ID', title as 'Title', author as 'Author', description as 'Description', issuedDate as 'Issued Date', dueDate as 'Due Date' FROM issuedBooks";
command.CommandText = query;
command.ExecuteNonQuery();
SQLiteDataAdapter da = new SQLiteDataAdapter(command);
DataSet ds = new DataSet();
da.Fill(ds, "issuedBooks");
int c = ds.Tables["issuedBooks"].Rows.Count;
dataGridView1.DataSource = ds.Tables["issuedBooks"];
dataGridView1.Sort(dataGridView1.Columns["Student ID"], ListSortDirection.Ascending);
dataGridView1.ReadOnly = true;
connection.Close();
this.Totals.Text = "Total Issued Books : " + Convert.ToString(c);
}
}
Have you tried,
foreach(DataGridView row in dataGridView1.Rows)
{
//check whether bookno. column in 'row' is less than 10
//and do something
}
I just read your comment that you want query from the database directly before displaying in datagridview, is that what you want?
For SQLite databases, check out this link, you can use standard SQL select statements to get the records based on your condition. Example SELECT * From <table> Where bookNum > 10
That should give you all the records with bookNum greater than 10.
First create your connection,
SQLiteConnection connection = new SQLiteConnection(connectionPath)
Then the dataadapter
SQLiteDataAdapter da = new SQLiteDataAdapter(query, connection);
Do your table mappings if any.
And then call da.Fill(ds, "issuedBooks");
I also noticed you were using As in your sql query for the column names. You can actually use tablemappings to map your database column name to the datatable column name. See this link.
Answer
public void onlyDueReport()
{
List<int> array = new List<int>();
string connectionPath = #"Data Source=Data\libraryData.dat;Version=3;New=False;Compress=True";
using (SQLiteConnection connection = new SQLiteConnection(connectionPath))
{
SQLiteCommand command = connection.CreateCommand();
connection.Open();
string query = "SELECT bookno as 'Book No.',studentId as 'Student ID', title as 'Title', author as 'Author', description as 'Description', issuedDate as 'Issued Date', dueDate as 'Due Date' FROM issuedBooks";
command.CommandText = query;
command.ExecuteNonQuery();
SQLiteDataAdapter da = new SQLiteDataAdapter(command);
DataSet ds = new DataSet();
da.Fill(ds, "issuedBooks");
int c = ds.Tables["issuedBooks"].Rows.Count;
if (c > 0)
{
for (int row = c; row > 0; row--)
{
string date = (string)(ds.Tables["issuedBooks"].Rows[c - row]["Due Date"]);
if (isLate(date))
{
int a = Convert.ToInt32(ds.Tables["issuedBooks"].Rows[c - row]["Book No."]);
array.Add(a);
}
}
}
query = "SELECT bookno as 'Book No.',studentId as 'Student ID', title as 'Title', author as 'Author', description as 'Description', issuedDate as 'Issued Date', dueDate as 'Due Date' FROM issuedBooks WHERE bookno IN (";
int[] cool = array.ToArray();
int cou = 0;
foreach (int a in cool)
{
query += a;
if (cou < cool.Length - 1) { query += ','; }
cou++;
}
query += ")";
Console.WriteLine(query);
command.CommandText = query;
command.ExecuteNonQuery();
DataSet ds1 = new DataSet();
da.Fill(ds1, "issuedBooks");
dataGridView1.DataSource = ds1.Tables["issuedBooks"];
this.Totals.Text = "";
Report_Viewer.StatusPText = " Total Pending Books : " + ds1.Tables["issuedBooks"].Rows.Count;
}
}
I am trying to bind sql data on textboxes against reading data from label my code is as below:
string sql1 = " select openbal from AccountMast where accname='" + comboBox1.Text + "' and companyID='" + label4.Text + "'";
SqlDataAdapter dap1 = new SqlDataAdapter(sql1, con);
DataSet ds1 = new DataSet();
dap1.Fill(ds1);
for (int p = 0; p < ds1.Tables[0].Rows.Count; p++)
{
if (label11.Text == "Dr")
{
txtopenbaldr.Text = Convert.ToString(ds1.Tables[0].Rows[p]["openbal"]);
}
if (label11.Text == "Cr")
{
txtopenbalcr.Text = Convert.ToString(ds1.Tables[0].Rows[p]["openbal"]);
}
}
//Label11 Bind by Sql.
string sql10 = " select obcat from AccountMast where accname='" + comboBox1.Text + "' and companyID='" + label4.Text + "'";
SqlDataAdapter dap10 = new SqlDataAdapter(sql10, con);
DataSet ds10 = new DataSet();
dap10.Fill(ds10);
for (int p = 0; p < ds10.Tables[0].Rows.Count; p++)
{
label11.Text = Convert.ToString(ds10.Tables[0].Rows[p]["obcat"]);
}
The label11 bound by sql data and it should display text "Dr" OR "Cr" at a time.
but it's not working as the label11.text not support for bind the data onto textboxes
I have two textboxes as below:
Opening Balance/Debit Opening Balance/Credit
txtopenbaldr.Text txtopenbalcr.Text
There are two textboxes which can databind on above condition: Remember only one textbox should be bind as per condition.
I am trying the trick but it's fail. Suggest the solution.
I'm assuming that you simply appended the code for label11.text at the end of your message, but that in reality label11.text is assigned before you try to set txtopenbaldr.Text or txtopenbalcr.Text.
If that's the case, I would make sure that label11.Text actually has the value Dr or Cr, and not DR or CR, as the comparisons will be case-sensitive.