Not getting all results from SqlDataReader - c#

Can anybody help me with the issue I'm seeing? For some reason when I run my page, I get my drop down lists to populate the data, however the first item in my database, per each SQL query, doesn't get populated.
For example, my database table is:
Category
1 Books
2 Clothing
3 Toys
4 Household Items
my first query -
SELECT Category FROM ProductCategories
my drop down list gets populated with
Clothing
Toys
Household Items
I have 2 other drop down lists I'm populating and those are doing the same thing. Once I get this figured out, I'll try to figure out the other problem I'm having with inserting the data in the database.
Thank you!
public partial class InsertItems : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
SqlConnection connection;
SqlCommand populateList;
SqlDataReader reader;
string connectionString = ConfigurationManager.ConnectionStrings["LakerBids"].ConnectionString;
connection = new SqlConnection(connectionString);
populateList = new SqlCommand("USE LakerBids SELECT Category FROM ProductCategories;" +
"USE LakerBids SELECT SubCategory FROM ProductSubCategories;" +
"USE LakerBids SELECT LName FROM Users", connection);
if (!IsPostBack)
{
try
{
connection.Open();
reader = populateList.ExecuteReader();
while (reader.Read())
{
pcategory.DataSource = reader;
pcategory.DataValueField = "Category";
pcategory.DataBind();
}
reader.NextResult();
while (reader.Read())
{
psubcategory.DataSource = reader;
psubcategory.DataValueField = "SubCategory";
psubcategory.DataBind();
}
reader.NextResult();
while (reader.Read())
{
user.DataSource = reader;
user.DataValueField = "LName";
user.DataBind();
}
reader.Close();
}
finally
{
connection.Close();
}
}
}
protected void AddItem(object sender, EventArgs e)
{
if (Page.IsValid)
{
SqlConnection connection;
SqlCommand insertData;
string connectionString = ConfigurationManager.ConnectionStrings["LakerBids"].ConnectionString;
connection = new SqlConnection(connectionString);
insertData = new SqlCommand("INSERT INTO Products (ProductName, ProductDesc, CategoryID, SubCatID, StatusID, UserID, ReservePrice, AuctionLength, BidID)" +
"VALUES (#ProductName, #ProductDesc, #CategoryID, #SubCatID, 1, #UserID, #ReservePrice, #AuctionLength, NULL)", connection);
insertData.Parameters.Add("#ProductName", System.Data.SqlDbType.NVarChar, 50);
insertData.Parameters["#ProductName"].Value = pname.Text;
insertData.Parameters.Add("#ProductDesc", System.Data.SqlDbType.NVarChar, 200);
insertData.Parameters["#ProductDesc"].Value = pdesc.Text;
insertData.Parameters.Add("#CategoryID", System.Data.SqlDbType.Int);
insertData.Parameters["#CategoryID"].Value = pcategory.SelectedIndex;
insertData.Parameters.Add("#SubCatID", System.Data.SqlDbType.Int);
insertData.Parameters["#SubCatID"].Value = psubcategory.SelectedIndex;
insertData.Parameters.Add("#UserID", System.Data.SqlDbType.Int);
insertData.Parameters["#UserID"].Value = user.SelectedIndex + 2;
insertData.Parameters.Add("#ReservePrice", System.Data.SqlDbType.Money);
insertData.Parameters["#ReservePrice"].Value = Convert.ToDecimal(reserveprice.Text);
insertData.Parameters.Add("#AuctionLength", System.Data.SqlDbType.Int);
insertData.Parameters["#AuctionLength"].Value = Convert.ToInt32(auctionlength.Text);
try
{
connection.Open();
insertData.ExecuteNonQuery();
Response.Redirect("Categories.aspx");
}
catch (Exception error)
{
dberror.Text = error.ToString();
}
finally
{
connection.Close();
}
}
}
}

You need to either use a DataSet or populate business entities within a collection and then bind to the collection.
List<Category> cats = new List<Category>();
while (reader.Read())
{
Category cat = new Category();
// fill properties from DataReader
cats.Add(cat);
}
pcategory.DataSource = cats;
pcategory.DataValueField = "Category";
pcategory.DataBind();

Sab0tr0n, I suspect one of two things are happening.
1) If you are saying the first item does not appear AFTER you do some kind of "Add Category" action, then it might be that the dropdown is populated BEFORE the insert completes. Meaning, you need to requery after allowing the insert to be committed to the database.
OR
2) Put a breakpoint on this line:
string connectionString = ConfigurationManager.ConnectionStrings["LakerBids"].ConnectionString;
Then confirm the connectionString is to the correct database. I've seen old config files that point to test or staging databases cause this kind of confusion.
Good luck. If these aren't the answer, maybe simplify your example to us or elaborate on exactly what you do with your application and when you see the problem.

The "reader.read()" statement in each block is actually reading the first row of data, so when you set the DataSource, the first row has already been read. Try taking it out
You should use "while (reader.Read())" if you want to iterate over each result, not bind the resulset in one step.
That being said, the comments about using a Dataset, seperating logic, etc., are valid

Related

Get list of IDs from Access Database using OleDbDataReader

Using a Microsoft Access database for a Web App Quiz Manager, I have table with a ID column that has a list of IDs which looks something like this:
ID Answer QuesDescription QuesAnswer QuestionNum
1 1 Example Example 1
3 3 Example Example 2
4 4 Example Example 3
6 1 Example Example 4
Using the query SELECT ID FROM (QuizName) with OleDbCommand I managed to get the ID values from the database and stored into OleDbDataReader reader. But i don't know how to get the ID values from the reader and store them as a String List. Does anyone know how to do this?
I've tried using stuff like
public List<string> GetIDValueFromQuestionNumber(string quizNumber)
{
try
{
string strSQL = string.Concat("SELECT count(ID) as RowCount FROM ", quizNumber);
List<string> resourceNames = new List<string>();
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
OleDbCommand command = new OleDbCommand(strSQL, connection);
connection.Open();
OleDbDataReader reader = command.ExecuteReader();
reader.Read();
int rowCount = (int)reader["RowCount"];
strSQL = string.Concat("SELECT ID FROM ", quizNumber);
command = new OleDbCommand(strSQL, connection);
using (reader = command.ExecuteReader())
{
while (reader.Read())
{
resourceNames.Add(" " + reader.GetString(0));
}
}
connection.Close();
for (int count = 0; count < rowCount; count++)
{
int value = (int)reader.GetValue(count);
resourceNames.Add(value.ToString());
}
}
return resourceNames;
}
catch (Exception e)
{
return null;
}
}
But to no luck.
I should note that these tables can vary in depth.
I suggest this approach.
Say a form - DataGridView to display our data.
And say a listbox to display the list of id that you build up into that List
So, this form:
And the button click code:
private void button1_Click(object sender, EventArgs e)
{
// load up our data list with Hotels
string strSQL =
#"SELECT ID, FirstName, LastName, City, HotelName
FROM tblHotelsA ORDER BY HotelName";
DataTable rstData = MyRst(strSQL);
dataGridView1.DataSource = rstData;
// now build up a list of id in to string colleciton
List<string> MyIDList = new List<string>();
foreach (DataRow MyOneRow in rstData.Rows)
{
MyIDList.Add(MyOneRow["ID"].ToString());
}
// Lets set the id list to a listbox
listBox1.DataSource = MyIDList;
}
DataTable MyRst(string strSQL)
{
DataTable rstData = new DataTable();
using (OleDbConnection conn = new OleDbConnection(Properties.Settings.Default.AccessDB))
{
using (OleDbCommand cmdSQL = new OleDbCommand(strSQL, conn))
{
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
And now we get/see this:
So, pull the table. Display it, do whatever.
Then use the SAME table, and simple loop each row, grab the ID and add to your list.
And of course, one would probably hide the "id" in the above list (just add the columns using edit columns - only add the ones you want). You can still get/grab/use ANY column from the data source - it not a requirement to display such columns.

Retrieve multiple items of data from database into one single label

I want to retrieve multiples values from database and display on one label.
My database design currently is:
courseid scholarshipid course
--------------------------------
1 1 maths
2 1 english
3 1 science
scholarshipid schName
-----------------------
1 moon
2 start
3 light
I would like to retrieve this information into one single label such as
Maths, English, Science
However, now I manage to retrieve one of it which is just maths.
This is my code in code behind:
protected void btnShowDetails_Click(object sender, EventArgs e)
{
string Selectedid = GVFBAcc.SelectedRow.Cells[1].Text;//get user id
int selectedIdtoPass = Convert.ToInt32(Selectedid);
courseBLL getRecord = new courseBLL();
addcourse courseRetrieve = new addcourse();
courseRetrieve = getRecord.getCourseDetail(selectedIdtoPass);
lbCourse.Text = courseRetrieve.course1 + "," + courseRetrieve.course1;
}
in my courseBLL
public addcourse getCourseDetail(int idcourse)
{
addcourse userObj = new addcourse();
courseDAL objtoPass = new courseDAL();
userObj = objtoPass.displayCourseInfo(idcourse);
return userObj;
}
in my DAL
public addcourse displayCourseInfo(int idcourse)
{
string strCommandText = "Select course from course where schokarshipid = #schokarshipid";
SqlCommand cmd = new SqlCommand(strCommandText, conn);
cmd.Parameters.AddWithValue("#scholarshipid", idcourse);
conn.Open();
SqlDataReader myReader = cmd.ExecuteReader();
addcourse userObj = new addcourse();
while (myReader.Read())
{
int sID = Convert.ToInt32(myReader["courseID"].ToString());
string course = myReader["course"].ToString();
userObj = new addcourse(sID, course);
}
myReader.Close();
return userObj;
}
Edited:
public addcourse displayCourseInfo(int idcourse)
{
var courses = new List<addcourse>();
string strCommandText = "Select statement here"
SqlCommand cmd = new SqlCommand(strCommandText, conn);
cmd.Parameters.AddWithValue("#scholarshipid", idcourse);
conn.Open();
SqlDataReader myReader = cmd.ExecuteReader();
while (myReader.Read())
{
int sID = Convert.ToInt32(myReader["scholarshipid"].ToString());
string course = myReader["course"].ToString();
courses.Add(new addcourse(sID,course));
}
myReader.Close();
return courses;
}
I have removed some fields for this purpose so that I will not confuse you
You should return a List<addcourse> from getCourseDetail() and from displayCourseInfo and then you can do this if your addCourse has Course property:
lbCourse.Text = string.Join(", ", courses.Select(x => x.Course));
If the property name is different then change x.Course to that.
So in your reader you will do this
var courses = new List<addcourse>();
while (myReader.Read())
{
int sID = Convert.ToInt32(myReader["courseID"].ToString());
string course = myReader["course"].ToString();
courses.Add( new addcourse(sID, course)) ;
}
return courses;
Your query is also wrong:
Select course, from course ss inner join where courseID =#courseID
So you should fix that and make sure you get the columns you need because right now it is only getting course column and it has syntax errors. Run your query directly against the db using management studio. Once your query works the copy paste it and replace where part with a parameter the way you have it right now.
EDIT
It seems you are still stuck with this so I will give you a more detailed answer; however, you should really study up on some fundamental programming concepts. Anyhow, here it is:
Your code behind:
protected void btnShowDetails_Click(object sender, EventArgs e)
{
string Selectedid = GVFBAcc.SelectedRow.Cells[1].Text;//get user id
// Make sure this is the scholarshipid or the whole thing will
// not work.
int selectedIdtoPass = Convert.ToInt32(Selectedid);
courseBLL courseRetriever = new courseBLL();
// Remember you will get a list here
List<addcourse> courses = courseRetriever.getCourseDetail(selectedIdtoPass);
// This will take the list and separate the course property with a comma and space
var courseNames = string.Join(", ", courses);
// Now assign it to the text property
lbCourse.Text = courseNames;
}
Your BLL:
// See here you are retuning a list
// But you need to pass the scholarshipid so you can get the courses for that scholarshipid
public List<addcourse> GerCourses(int scholarshipId)
{
courseDAL courseRetriever = new courseDAL();
// Get the list
List<addcourse> courses = courseRetriever.GetCourses(scholarshipId);
return courses;
}
Your DAL:
// See here you are retuning a list
// But you need to pass the scholarshipid so you can get the courses for that scholarshipid
public List<addcourse> GetCourses(int scholarshipId)
{
// Make sure your query is correct, see you have spelling mistakes
// it should be scholarshipid not schokarshipid. it has to match the column in your database
// Make sure your table is called course and it has 3 columns: 1. courseid 2. course
// 3. scholarshipid or this query will not work
string strCommandText = "Select courseid, course from course where scholarshipid = #scholarshipId";
SqlCommand cmd = new SqlCommand(strCommandText, conn);
cmd.Parameters.AddWithValue("#scholarshipid", scholarshipId);
conn.Open();
SqlDataReader myReader = cmd.ExecuteReader();
// create a list so we can hold all the courses
List<addcourse> userObjs = new List<addcourse>();
// This will read one row at a time so keep reading until there are no more records
while (myReader.Read())
{
int sID = Convert.ToInt32(myReader["courseid"].ToString());
string course = myReader["course"].ToString();
addcourse userObj = new addcourse(sID, course);
// add it to the list
userObjs.Add(userObj);
}
myReader.Close();
// return the list
return userObjs;
}
A few more tips:
Give your methods more meaningful names. See the names I gave them GetCourses, now it reads like English and it is easy to follow.
Your class addcourse should be called Course. addcourse sounds like an action "add course", that could be a good name for a method if you were adding courses. Also use Pascal notation for class names and method names. Use Camel casing for arguments, parameters and local variables.
Learn how to use the Visual Studio debugger. Go watch some YouTube videos on Visual Studio Debugger.
Create a for loop then add it on the variable you are using

Display a list of item to CheckListBox when comboBox item is selected

I have a windows form application. Inside the form, I have a ComboBox and a list box. When I select the comboBox, I want to display a list of item that the user can check in the checkListBox, I figured out how to bind data to comboBox part but I am not sure how to display a list of values so that the user can select in the checkListBox. Let say I have a list of items that stored in a SQL database call item_table, how can I display it to the checkListBox according to when I select from the comboBox? Code for reference will be appreciated. Thanks
For example,
let say the user select "Amy" from the comboBox, the checkListBox will display a list of item "item 1, item2, item3, item4".
when the user select "Brad" from the comboBox, it will display a list of item: "item2, item5, item10
etc
Here is my database table in (SQL) server
user_Detail
In my user_Detail table , I have 10 user and each of them have a primary key (userId) and a column (userName);
item_Detail
In my item_Detail table, I have 20 items and they also have a primary key (itemId) and a column (itemName)
In the sql console, I inner join the two table (which I am not sure if I need to do the same in my SqlCommand in the code )
Here is my sql command in the console.
select
user_Detail.userId,
user_Detail.userName,
item_Detail.itemId,
item_Detail.itemName
from
item_Detail
INNER JOIN user_Detail ON user_Detail.userId = item_Detail.itemId
Here is my code
namespace Test {
public partial class MainForm: Form {
SqlConnection myConn;
SqlCommand myCommand;
SqlDataReader myReader;
SqlDataAdapter myDa;
DataTable dt;
DataSet ds = new DataSet();
public MainForm() {
InitializeComponent();
// loadComboBox
loadComboBox();
}
//Connect to my db to fetch the data when the application load
private void loadComboBox() {
myConn = new SqlConnection("Server = localhost; Initial Catalog= dbName; Trusted_Connection = True");
string query = "Select * from user_Detail";
myCommand = new SqlCommand(query, myConn);
try {
myConn.Open();
myReader = myCommand.ExecuteReader();
string s = "<------------- Select an item ----------->";
itemComboBox.Items.Add(s);
itemComboBox.Text = s;
while (myReader.Read()) {
//declare a string
object userId = myReader[userId"];
object userName = myReader["userName"];
//my comboBox named userComboBox
userComboBox.Items.Add(userName.ToString());
}
} catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}
//Display some items here (this is my checkListBox
private item_checkListBox(Object sender, EventArgs e){
}
private void load_item(){
}
I wish this could help you.
First, i just want to fix your loadComboBox() because reading it might lead to confusion.
private void loadComboBox() {
myConn = new SqlConnection("Server = localhost; Initial Catalog=dbName; Trusted_Connection = True");
string query = "Select * from user_Detail";
myCommand = new SqlCommand(query, myConn);
try {
myConn.Open();
myReader = myCommand.ExecuteReader();
string s = "<------------- Select an item ----------->";
itemComboBox.Items.Add(s);
itemComboBox.Text = s;
while (myReader.Read()) {
//declare a string
string userId = myReader["userId"].toString();
string userName = myReader["userName"].toString();
//my comboBox named userComboBox
userComboBox.Items.Add(userName);
}
myConn.Close();
} catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}
Make sure to close sql connections after using it. Just open it again if youre going to use it.
Now, you added the userName of your users on your combobox.
Next lets create an event that will be fired whenever you choose from your combobox.
userComboBox.SelectedIndexChanged += (o,ev) => { ChangeCheckListItems(); };
The code above can be read as "if userComboBox changed selected index, call ChangeCheckListItems() method." Whenever you change selection, we will call the said method. You can put that code on your class constructor.
Now what does ChangeCheckListItems() method must contain.
private void ChangeCheckListItems(){
myCheckListBox.Items.Clear();
string selectedText = userComboBox.Text;
switch(selectedText){
case "Amy":
AddItemsForAmy();
break;
case "Brad":
AddItemsForBrad();
break:
}
}
So first, we make sure we clear the myCheckListBox before adding the items to avoid duplication since this method trigger every selection change.
Next we get the selected text from the userComboBox.
Then we will use a switch to choose what we will do depends on the selected userComboBox.
AddItemsForAmy() and AddItemsForBrad() are only example methods.
For example:
private void AddItemsForAmy(){
myConn = new SqlConnection("Server = localhost; Initial Catalog=dbName Trusted_Connection=true;"
string query = "Select * from item_Detail where itemId % 2 = 0"
myCommand = new SqlCommand(query, myConn);
try{
myConn.Open();
myReader = myCommand.ExecuteReader();
while(myReader.Read()){
string itemName = myReader["itemName"].toString();
myCheckListBox.Items.Add(itemName);
}
myConn.Close();
}
catch(SqlExcetion ex){
MessageBox.Show(ex.Message);
}
}
So in my example above, I selected all items with itemId that are even numbers.
And then on while() part, I added those items to the checklistbox.
Its your choice on what items are you going to display for Amy,Brad and other possible users on you database. You can also use parameterized method for shorter solution. Hope this helps. Sorry if its so long.

Getting data from each row in a SQL Server CE database

I have done this before, but for the life of me I can't remember how this worked.
I have a database that has a bunch of rows with data in them like names and ID numbers. What I need to do is populate a treeview from names in the database. I am running up against an issue just getting the reader to read multiple rows in the database. It only seems to be reading the first row and not subsequent rows. the actual task would be similar to below :
For each row in database add a parent node to treeview where the name is = to (reader[4].ToString()). That's about it. At the moment all I am trying to do is just get it to pop a messagebox showing that it's reading the multiple rows.
Please what am I missing to get this working?
SqlCeConnection conn = null;
try
{
using (conn = new SqlCeConnection("Data Source =" + ConfigurationFile + "; Password =*********"))
{
conn.Open();
SqlCeCommand cmd = conn.CreateCommand();
cmd.CommandText = "select * from t_mainprofiles";
cmd.ExecuteNonQuery();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
ID = (Convert.ToInt32(reader[1]));
profileID = (Convert.ToInt32(reader[2]));
profileNAME = (reader[4].ToString().Trim());
profileLOC = (reader[5].ToString().Trim());
profileCHILD = (reader[6].ToString().Trim());
}
MessageBox.Show(profileNAME);
reader.Close();
}
}
catch(Exception error)
{
MessageBox.Show(""+error);
System.Diagnostics.Process.GetCurrentProcess().Kill();
}
finally
{
conn.Close();
}
Try removing the line cmd.ExecuteNonQuery();
Here is an example from MSDN
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.read(v=vs.110).aspx

SQL rows are not being deleted

So I have this code that is designed to delete a row in mySQL server database judging by what is selected in my list box. Here is the code I have to remove the rows:
private void remove_btn_Click(object sender, EventArgs e)
{
try
{
if (Calls_lsb.SelectedItem == null)
MessageBox.Show("Please select an item for deletion.");
}
else
{
int i = Calls_lsb.SelectedIndex;
if (i > 0)
{
SqlConnection connection = new SqlConnection(//My Connection String);
string sqlStatement1 = "DELETE FROM Records WHERE CallID = #Id";
string sqlStatement2 = "DELETE FROM Calls WHERE CallID = #Id";
connection.Open();
SqlCommand cmd1 = new SqlCommand(sqlStatement1, connection);
cmd1.Parameters.AddWithValue("#Id", Calls_lsb.Items[i]);
cmd1.ExecuteNonQuery();
SqlCommand cmd2 = new SqlCommand(sqlStatement2, connection);
cmd2.Parameters.AddWithValue("#Id", Calls_lsb.Items[i]);
cmd2.ExecuteNonQuery();
connection.Close();
Calls_lsb.Items.Remove(Calls_lsb.Items[i]);
}
else
{
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
I get no exceptions and I have similar code that adds records that works fine. I tried stepping into the code but it all seemed fine. It simply just does not delete the row from the database. It removes the correct item from the list, just not the database.
If anyone could shine some light on this situation that would be great, thanks!
Edit : Ok, I seem to have fixed the problem. I just removed the whole i = selected index stuff and replace the 'Calls_lsb.Items[i]' with '(Calls_lsb.SelectedIndex + 1)'. I don't really understand why I was getting an exception when I tried to add 1 to i as this is basically doing the same thing.
Replace your below line code.
cmd1.Parameters.AddWithValue("#Id", Calls_lsb.Items[i]);
//with
cmd1.Parameters.AddWithValue("#Id", Calls_lsb.Items[i].Value);
and
cmd2.Parameters.AddWithValue("#Id", Calls_lsb.Items[i]);
// with
cmd2.Parameters.AddWithValue("#Id", Calls_lsb.Items[i].Value);

Categories

Resources