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
Related
I'm working on a project where the customer can make an order of infinite products, I need my code to read every single product ID of his order.
For this to work, it needs to be in a loop, and I could only find ways to make this without a loop, with finite products on the internet.
I tried using SELECT like this:
string selectCod = "SELECT id FROM order";
MySqlCommand selectCodCmd = new MySqlCommand(selectCod, BDconnection);
reader = selectCodCmd.ExecuteReader();
while (reader.Read())
{
}
reader.Close();
But I can't think of anything to put inside the while, I tried using x = reader[0].ToString(); but I only get the last product ID.
If anyone could help me I would appreciate it
Edit1:
Thanks a lot, It worked! Here's the code if anyone has the same problem in future:
string selectCod = "SELECT id FROM OrderItens";
var selectCodCmd = new MySqlCommand(selectCod, BDconnection);
reader = selectCodCmd.ExecuteReader();
var OrderItensId = new List<string>();
while (reader.Read())
{
OrderItensId.Add(reader["id"].ToString());
}
reader.Close();
foreach(string Code in OrderItensId)
{
string CodeAmount = "SELECT amount FROM OrderItens
WHERE id = "+ Code +"";
var CodeAmountCmd = new MySqlCommand(CodeAmount, BDconnection);
reader = CodeAmountCmd.ExecuteReader();
int OrderAmount = 0;
while (reader.Read())
{
OrderAmount = Int32.Parse(reader[0].ToString());
}
reader.Close();
string UpdateStock = "UPDATE Stock
SET amount = amount - "+OrderAmount+"
WHERE id = "+ Code +"";
var UpdateStockCmd = new MySqlCommand(UpdateStock, BDconnection);
reader = UpdateStockCmd.ExecuteReader();
while (reader.Read()) { }
reader.Close();
}
Well, as i understand, you need to get all the products ids from one specific order right?
With this, you only getting all the orders ids from your table orders
string selectCod = "SELECT id FROM order";
First, you will need the order id and i suppose that you have a table called orderItens or something like that..
Then, you get all the itens for that order with a select like this:
string selectCod = "SELECT id FROM orderItens where orderId = #orderId";
Then just create a loop like this
var orderItensIds = new List<int>();
while (reader.Read())
{
orderItensIds.Add(int.Parse(reader["id"]));
}
reader.Close();
return orderItensIds
There you have a list with all the itens id from your order
You are using it right, you just need to put the code var x = reader[0].ToString(); into while loop to let it get all id in all rows.
For example, I will use a listId list to save Id list. You can use it to calculate or insert later.
string selectCod = "SELECT id FROM order";
MySqlCommand selectCodCmd = new MySqlCommand(selectCod, BDconnection);
reader = selectCodCmd.ExecuteReader();
var listId = new List<int>();
while (reader.Read())
{
var x = reader[0].ToString();
listId.Add(int.Parse(x));
}
reader.Close();
// Use this list to any where you want
listId
I am using the following code to get a user's full name, then
I am attempting to use the user's full name to then find out their ID, department and job title. Is there a way to use the DirectoryEntry to also acquire the EmplID from active directory?
public void Connect()
{
//method to connect to database and autofill user information
string n = GetFullName();
string[] names = n.Split(',');
FullName.Text = n;
fn = names[1];
ln = names[0];
try
{
var connection = ConfigurationManager.ConnectionStrings["PSHRDataConnection"];
SqlConnection ds = new SqlConnection(connection.ConnectionString);
ds.Open();
SqlCommand com = new SqlCommand("Select EmpID, psd.Descr, JobCode from PSHRData ps Inner Join PSDept psd on psd.DeptID=ps.DeptID where ps.LastName =#lname and ps.FirstName=#fname", ds);
com.Parameters.AddWithValue("#fname", fn);
com.Parameters.AddWithValue("#lname", ln);
SqlDataReader reader = com.ExecuteReader();
while (reader.Read())
{
EmID.Text = reader["EmpID"].ToString();
dept.Text = reader["Descr"].ToString();
jobtitle.Text = reader["JobCode"].ToString();
}
ds.Close();
}
catch (SqlException)
{
}
}
This works properly when I replace the 2 parameters with my actual first and last name, but does not seem to want to accept the parameters for what ever reason (no error is thrown, just doesn't populate the information that it is supposed to)
I have a list that retrieves the student's grades by passing in a list of student class,
it then pulls the student grades by querying the student's name through the database. This code works fine however, when the studentList increases in size, this code gets really slow to execute,
What is the proper method for looping a list through a sql query?
private List<StudentClass> getStudentGrades(List<StudentClass> studentList)
{
for (int i =0; i < studentList.Count; i++)
{
string sqlcommand = "SELECT StudentGrades FROM Students WHERE StudentName=#StudentName";
conn.Open();
using (SqlCommand cmd = new SqlCommand(sqlcommand, conn))
{
cmd.Parameters.AddWithValue("#StudentName", studentList[i].StudentName);
cmd.ExecuteNonQuery();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Reader())
{
studentList[i].StudentGrades = int.Parse(reader["StudentGrades"].ToString());
}
}
}
return studentList;
}
public class StudentClass
{
public string StudentName {get; set; }
public int StudentGrades {get; set; }
}
First of all - you're unnecessary executing your command twice. You're calling ExecuteNonQuery first (it will has no effect since ExecuteNonQuery doesn't returns data, but it slows down execution since request actually being passed to SQL server and being executed). Then you're calling ExecuteReader from which you're actually retrieving data.
Second issue - you're executing new query for each student. So if you will have 1000 students in list - it will be 1000 queries executed.
Consider getting all data from database first, and then update your studentList accordingly.
Something like getting SELECT StudentName, StudentGrades FROM Students first, save result to some dictionary (or wherever you want) and then do your loop over studentList
private List<StudentClass> getStudentGrades(List<StudentClass> studentList)
{
string sqlcommand = "SELECT StudentGrades FROM Students WHERE StudentName=#StudentName";
var conn = new SqlConnection();
SqlCommand cmd = new SqlCommand(sqlcommand, conn);
cmd.Parameters.Add("#StudentName");
using (conn)
{
conn.Open();
for (int i = 0; i < studentList.Count; i++)
{
cmd.Parameters[0].Value= studentList[i].StudentName;
studentList[i].StudentGrades = (int)cmd.ExecuteScalar();
}
}
return studentList;
}
Note: You should retrieve the whole list in one query, it would be much much better.
As other users have pointed out, you don't need the executenonquery.
But the bigger issue is that your SQL statement only returns one student's data at a time. Is there another field you can use to select all students in a group at at time? I.e., is there a "class" field or something like that, so you can do something like:
select studentgrades
from students
where class = #class
If not, you can still write a kind of ugly sql statement with an in clause. So:
select studentgrades
from studens
where studentname in ('studentname1', 'studentname2', etc. )
Using that approach, you'd modify your code to be something like this:
private List<StudentClass> getStudentGrades(List<StudentClass> studentList)
{
string studentListParam = "";
foreach(StudentClass student in studentlist)
{
// blah blah stuff to only add comma if not first element
studentListParam = studentListParam + ", '" + student.StudentName + "';
}
string sqlcommand = #"
SELECT StudentName, StudentGrades
FROM Students
WHERE StudentName in (" + studentlist + ")";
conn.Open();
using (SqlCommand cmd = new SqlCommand(sqlcommand, conn))
{
cmd.Parameters.AddWithValue("#StudentName", studentList[i].StudentName);
cmd.ExecuteNonQuery();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Reader())
{
StudentClass student = studentList.Where(s => s.StudentName == string.Parse(reader["StudentName"]);
student.StudentGrades = int.Parse(reader["StudentGrades"].ToString());
}
}
}
return studentList;
}
public class StudentClass
{
public string StudentName {get; set; }
public int StudentGrades {get; set; }
}
Obviously you'd need some null checks and various other bits of error checking to make this really production ready, but that should be a starting point.
(Also, note that this approach doesn't try to parameterize the query, so you'd lost a little bit of parse time, but's going to be orders of magnitude less than you're losing with the multiple queries.)
I have 2 different databases and I need to get results of their queries into 1 structure:
struct my_order
{
public int Id_N
public int OrderId;
public string Discount;
public string CustomerId;
public string ShipAddress;
}
My queries:
my_order ret = new my_order();
SqlConnection con = open_sql(firstDB);
string firstQuery= #" SELECT OrderId, Discount FROM Orders
WHERE Id = " + id_n.ToString(); //some ID that I got earlier
SqlCommand command = new SqlCommand(firstQuery, con);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
ret.Id_N = id_n;
ret.OrderId = reader["OrderId"].ToString();
ret.Discount = reader["Discount"].ToString();
}
SqlConnection second_con = open_sql(secondDB);
string secondQuery= #" SELECT CustomerId, ShipAdress FROM Details
WHERE Id = " + id_n.ToString();
//id_n - some ID that I got earlier(the same as in the first query)
SqlCommand secondCommand = new SqlCommand(secondQuery, second_con);
SqlDataReader secondReader = secondCommand.ExecuteReader();
while (secondReader.Read())
{
ret.Id_N = id_n;
ret.CustomerId = secondReader["CustomerId"].ToString();
ret.ShipAddress = secondReader["ShipAddress"].ToString();
}
The problem is that compiler get the result from the firstQuery and doesn't from the secondQuery. It doesn't get into while(secondReader.Read()).
How to correct it?
PS: I change the code and queries a little bit, because my is too big, but the question is the same.
Regards,
Alexander.
Shooting into the blue here without an error or a more detailed description of what is going wrong, but you have a typo in your code:
string secondQuery= #" SELECT CustomerId, ShipAdress FROM Details WHERE Id = " + id_n.ToString();
ret.ShipAddress= secondReader["ShipAddress"].ToString();
You are writing ShipAdress with one and 2 d's.
Choose the correct version
The reason why it doesn't go into the while (secondReader.Read()) { ... } is because the second query does not return any rows, because there are no rows in table Details with the specified Id value.
you may use the propriete HasRows and IsDBNull(columnIndex) method to check if it contains data
if (secondReader.HasRows)
// Get data
else
//there is no data
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