I have created a search function that returns product data in a DataGridView (data is coming from local database), it does work but I need to have control over returned data in my grid view.
Current behavior
It returns all columns of database row in DataGridView
What I want
Returning only 2 or 3 columns of searched item instead of all columns
Create new list of searched items so I can edit those returned data
Logic
Search for product
Get product name and price from database, add custom quantity field make new list and add this item to show in DataGridView
Be able to change quantity field in DataGridView
Code
Here is my search code that returns all columns of product table
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["SampleDatabaseWalkthrough.Properties.Settings.SampleDatabaseConnectionString"].ConnectionString))
{
if (cn.State == ConnectionState.Closed)
cn.Open();
using (DataTable dt = new DataTable("Products"))
{
using (SqlCommand cmd = new SqlCommand("select * from Products where Id=#Id or Name like #Name", cn))
{
cmd.Parameters.AddWithValue("Id", searchBox.Text);
cmd.Parameters.AddWithValue("Name", string.Format("%{0}%", searchBox.Text));
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(dt);
// Following line will show all columns of founded product and replace it with next search result
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
selectedItems.DataSource = dt;
}
}
}
PS: Code above finds products based on id or name entered in search field and return all columns of product row.
Idea:
I think I can be able to create my list after finding product but the issue I'm facing is that I'm not sure how to get those specific columns from my dt (table row),
Here is what I've tried and failed (commented)
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["SampleDatabaseWalkthrough.Properties.Settings.SampleDatabaseConnectionString"].ConnectionString))
{
if (cn.State == ConnectionState.Closed)
cn.Open();
using (DataTable dt = new DataTable("Products"))
{
using (SqlCommand cmd = new SqlCommand("select * from Products where Id=#Id or Name like #Name", cn))
{
cmd.Parameters.AddWithValue("Id", searchBox.Text);
cmd.Parameters.AddWithValue("Name", string.Format("%{0}%", searchBox.Text));
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(dt);
//selectedItems.DataSource = dt; //<-- changed with lines below
List<string> items = new List<string>();
items.Add(dt); // <-- here is the issue (it expect to get string of my table row let say: Price column, but I don't know how to get Price column value from dt)
selectedItems.DataSource = items;
}
}
}
PS: code above is just idea and obviously I am not sure if it is best way to do it or not that's why I'm asking here :)
Any suggestions?
Update
I've created new class and added my data to that class as following
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public string Price { get; set; }
public string Qty { get; set; }
}
Then in my query I added
List<Item> itemList = new List<Item>();
for (int i = 0; i < dt.Rows.Count; i++)
{
Item item = new Item();
item.Id = Convert.ToInt32(dt.Rows[i]["Id"]);
item.Name = dt.Rows[i]["Name"].ToString();
item.Price = dt.Rows[i]["SellPrice"].ToString();
item.Qty = dt.Rows[i]["Qty"].ToString();
itemList.Add(item);
}
selectedItems.DataSource = itemList;
Now it does return data in my selectedItems but when I search for next product instead of adding it to the list it replace it with first product.
According to your sql query you are selecting all columns of the table.
To get the specific columns please change your sql query as such:
SqlCommand cmd = new SqlCommand("select Products.id, Products.name from Products where Id=#Id or Name like #Name", cn);
Thank you.
As per my understanding based on the comments, you are looking for some Linq code.
You only need to convert your result to a list that you could use.
Here is some code that might help you achieve this.
var result = dt.AsEnumerable().Select(x=> new {
Id = x["Id"],
Name = x["Name"],
Quantity = {Your Logic here}
});
selectedItems.DataSource = result;
You can then assign result to your datasource. You did not specify what your datasource is assigned to (selectedItems) so I do not know what type it is. but this should theoretically work. Just remove Quantity = {Your Logic here} from the code and see if it display's after which you could then just add it back and populate what you want Quantity to be
UPDATE
Because selectedItems is a DataGridView it requires a DataTable object to display the data. In which case you can not use an anonymous list as I created you would need something like this.
DataTable dtResult = new DataTable();
dtResult.Columns.Add("Id");
dtResult.Columns.Add("Name");
dtResult.Columns.Add("Quantity");
var result = dt.AsEnumerable().Select(x=> dtResult.Rows.Add(x["Id"],
x["Name"],
{Your Logic for Quantity here}
));
selectedItems.DataSource = result;
If you want to test this solution you can create a console application in c# and do something like where you can see the datasource is correct.
You could refer to the following code to show specific column data from database in winform datagirdview.
private void button1_Click(object sender, EventArgs e)
{
string str = "str";
SqlConnection connection = new SqlConnection(str);
connection.Open();
string sql = "select * from Product where Id=#Id or Name like #Name";
SqlCommand command = new SqlCommand(sql,connection);
command.Parameters.AddWithValue("#Id", textBox1.Text);
command.Parameters.AddWithValue("#Name", string.Format("%{0}%", textBox1.Text));
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataTable table = new DataTable();
adapter.Fill(table);
var dt = from t in table.AsEnumerable()
select new
{
//Name=t.Field<string>("Name"), //The same way to show other columns data
Price = t.Field<string>("Price")
};
dataGridView1.DataSource = dt.ToList();
}
Result:
Database:
Related
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.
I have a DataGridView with 4 columns. The code I'm using to build its datasource is this:
DataTable vTbl = new DataTable();
using(SqlConnection c = new SqlConnection(ConStr))
{
string query = "select site, username, password, notes from Passwords order by site, username";
using(SqlDataAdapter da = new SqlDataAdapter(query, c))
{
c.Open();
vTbl.Clear();
da.Fill(vTbl);
c.Close();
}
}
dataGridView1.DataSource = vTbl;
Now the fourth column which contains notes is a data type of nvarchar(max) in the table. So what I'd like to do is just show a mark (like an X) if this field is not empty or nulled and show nothing if the field IS empty or nulled.
I'm thinking there is something to do with the query variable, but I just can't place it.
Can someone please help me out?
Thanks,
Bob Gatto
Here is simple way using linq :
vTbl.Columns.Add("X", typeof(string));
foreach(DataRow row in vTbl.AsEnumerable())
{
if (row.Field<string>(3).Length > 0)
{
row[4] = "X";
}
}
vTbl.Columns.Remove("Column Name");
I want to grab data from database and display in labels based on what the user selects in the list view.
I'm going off an example that does this with two list views, but I don't know how to do it when I'm sending data to a label.
This is the list view example I'm using (my label code is below this)
private void PopulateRecipeIngredients()
{
string query = "SELECT a.Name FROM Ingredient a " +
"INNER JOIN RecipeIngredient b ON a.Id = b.IngredientId " +
"WHERE b.RecipeId = #RecipeId";
// # is a parameter
using (connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
// whatever recipe is selected in lstRecipes box, get the id of that and pass into query above
command.Parameters.AddWithValue("#RecipeId", lstRecipes.SelectedValue);
// DataTable holds the data return from query
DataTable ingredientTable = new DataTable();
// SqlDataAdapter object adapter fills the ingredientTable DataTable object with results from query
adapter.Fill(ingredientTable);
// Display value of Name ex. salad
lstIngredients.DisplayMember = "Name";
// Id column is how we reference
lstIngredients.ValueMember = "Id";
// connect list box on form to data in recipeTable
lstIngredients.DataSource = ingredientTable;
}
}
MY CODE:
private void PopulateCourseDetails()
{
string query = "SELECT * FROM Course_Info WHERE Id = #CourseId";
using (connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
command.Parameters.AddWithValue("#CourseId", lstCourses.SelectedValue);
DataTable courseTable = new DataTable();
adapter.Fill(courseTable);
lblCourseId.Text = "Course_id";
lblCourseSection.Text = "Course_section";
lblCourseName.Text = "Course_name";
lblCourseDay.Text = "Course_day";
lblCourseStartTime.Text = "Course_start_time";
lblCourseEndTime.Text = "Course_end_time";
lblCourseProfessor.Text = "Course_professor";
lblCourseProfessorEmail.Text = "Course_professor_email";
lstCourses.ValueMember = "Id";
}
}
lblCourseId.Text = (string)courseTable.Rows[0]["Course_id"]
should work as long as you have one row in the result table
Assuming that your DataTable has now been properly populated, you now have a table with a number of rows.
First you need to pull out the first row
var row = courseTable.Rows.FirstOrDefault();
Now you've got a row with a number of columns. You can access each column by either index or column name.
lblCourseId.Text = row[0];
If you want the label to maintain it's header, you can do something like
lblCourseId.Text = "Course_id: " + row[0];
There are 2 columns, one with name and the other with email addresses. I want to be able to display the names from the name's column in a dropdown but user the email in the next column when the form is submitted on my asp page.
public void FillAssignedToDropdownOnsite()
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["onsite_db"].ConnectionString);
string query = "SELECT Name, EmailAddress FROM OnsiteData ";
SqlCommand cmd = new SqlCommand(query, con);
SqlDataAdapter adpt = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
cmd.Connection.Open();
adpt.Fill(dt);
cmd.Connection.Close();
lstAssignedTo.DataSource = dt;
lstAssignedTo.DataTextField = "Name";
lstAssignedTo.DataBind();
lstAssignedTo.Items.Insert(0, "Select Onsite Tech");
}
Sql table is OnsiteData
columns are name and emailaddress
Form has a dropdown that sends an email.
It seems that your tag is misplaced. Supposing that this is ASP.NET instead of ASP-Classic and lstAssignedTo is a DropDownList I suggest to use the DataValueField set to EmailAddress
lstAssignedTo.DataSource = dt;
lstAssignedTo.DataTextField = "Name";
lstAssignedTo.DataValueField = "EMailAddress";
lstAssignedTo.DataBind();
when needed you could extract the email address for the selected user reading the Value property
if(lstAssignedTo.SelectedValue != null)
{
string email = lstAssignedTo.SelectedValue.ToString();
......
}
Not sure it's what you want :
lstAssignedTo.DataSource = dt;
lstAssignedTo.DataTextField = "Name";
lstAssignedTo.DataValueField = "EmailAddress"
lstAssignedTo.DataBind();
lstAssignedTo.Items.Insert(0, "Select Onsite Tech");
Like this the name is displayed and you can get the corresponding email with
var value = lstAssignedTo.SelectedValue;
I had windows form and I added combobox which bin data from database I added my code but this error apeared (invalid column name Category) altought the name was right .
public Category()
{
InitializeComponent();
CategoryParent();
}
private void CategoryParent()
{
using (SqlConnection Con = GetConnection())
{
SqlDataAdapter da = new SqlDataAdapter("Select Category.Category,Category.Id from Category", Con);
DataTable dt = new DataTable();
da.Fill(dt);
CBParent.DataSource = dt;
CBParent.DisplayMember = "Category";
CBParent.ValueMember = "Id";
}
}
Change your query like this,
Select Category.Category as CatName ,Category.Id from Category
i-e use an alias like "CatName" for your column and set Display member like this,
CBParent.DisplayMember = "CatName";
Hope it shall help.
I checked the connection and I found the connectionstring was wrong