I have an asp.net page with two listboxes and a save button. The user needs to transfer items from listbox1 to listbox2 according to his order I mean that user can choose witch item come in the first place and which come next.
After that my system suggest the results (most commonly) that achieve the ordered items, I hope you understand
I did the transfer method between the two listboxes and it work good. But I'm stuck in the save method, it can save the items after being in listbox2 but not in the same order of transferring (user order).
Here is my code for save button:
protected void Button1_Click(object sender, EventArgs e)
{
string strConnString = ConfigurationManager.ConnectionStrings["ConnectionString2"].ConnectionString;
string str;
OracleCommand com;
OracleConnection con = new OracleConnection(strConnString);
try
{
con.Open();
for (int i = 0; i < ListBox2.Items.Count; i++)
{
str = "insert into Criteria values('" + ListBox2.Items[i].ToString() + "')";
com = new OracleCommand(str, con);
com.ExecuteNonQuery();
}
LabOut.Visible = true;
LabOut.Text = "Upload succesful!";
con.Close();
//Response.Write("Inserted");
}
catch (Exception)
{
LabOut.Visible = true;
LabOut.Text = "Upload failed!";
}
finally
{
con.Close();
con.Dispose();
}
}
The problem here is that database tables do not inherently have a concept of order. Retrieving rows from a table never guarantees an order unless you use a order by clause.
You should add an additional column to your table (named, for example, "Sequence" or "Order"). It can be an int or some other sortable value. You would then need to modify your insert statement:
str = "insert into Criteria(ItemValue, Sequence) values('" + ListBox2.Items[i].ToString() + "'," + i.ToString() + ")";
and retrieve the list using
str = "Select ItemValue from Criteria order by Sequence"
#fifo follow me
1st add a column in your database say it is SeqNo.
Then save your data with that. I mean generate SeqNo. for each listbox2 item and save it.
When you will fetch data from database into lintbox2 then use sql/linq ORDER BY on SeqNo. column and display them on which Order that you were saved. Simple.. :)
Related
I made a same event for 2 comboboxes to populate my input controls so the user can see what they would be deleting or updating. When I made separate events it worked but upon making the same event it does not work. What conditions should i put in the if-statements
on this if condition the error i get id "Index was outside the bounds of the array"
private void BoardComboBo(object sender, EventArgs e)
{
if (comboBox12.SelectedIndex!=0)//error is here
{
con.Open();
cmd = new SqlCommand("Select * from Users where user_Id='" + comboBox12.Text + "';", con);
SqlDataReader DR1 = cmd.ExecuteReader();
if (DR1.Read())
{
//code to fill textboxes
}
con.Close();
}
if(comboBox1.SelectedIndex!=0)//error is here
{
//to split combobox values
string selectedvalue = comboBox1.Text;
split = selectedvalue.Split();
//add values on fields
con.Open();
cmd = new SqlCommand("Select * from Users where firstName='" + split[0] + "' and lastName='" + split[1] + "';", con);
SqlDataReader DR1 = cmd.ExecuteReader();
if (DR1.Read())
{
//code to fill textboxes
}
con.Close();
}
}
I changed the second if condition too:
if (comboBox12.Text!=" ")// this works
{
//to split combobox values
string selectedvalue = comboBox1.Text;
split = selectedvalue.Split();
//add values on fields
con.Open();
cmd = new SqlCommand("Select * from Users where firstName='" + split[0] + "' and lastName='" + split[1] + "';", con);
SqlDataReader DR1 = cmd.ExecuteReader();
if (DR1.Read())
{
//code to fill textboxes
}
con.Close();
}
I am now getting the same error above when i try to select by user_Id
In the method signature, the sender object is the one that's triggering the event, so we can just cast it to a ComboBox and check if it's one that we care about:
private void BoardComboBo(object sender, EventArgs e)
{
var comboBox = sender as ComboBox;
if (comboBox == comboBox1)
{
// comboBox1 code here
}
else if (comboBox == comboBox12)
{
// comboBox12 code here
}
}
However at this point, you may as well have two separate events. Since there is no significant duplicated code that's specific to the ComboBoxes, refactoring them into one event only makes the code more cumbersome.
Regarding the "Index was outside the bounds of the array" error, the only place you reference an index is when you split the Text property of comboBox1. Most likely, the Text does not have any whitespace in it, so Split is returning a single-item array. Then the problem is when you try to access an index that doesn't exist here:
split[1] // Here you're attempting to access an index that doesn't exist
To fix this issue, check the Length of the array before accessing indexes that may not exist, maybe something like:
// Set the last name to an empty string if it didn't exist
var lastName = split.Length > 1 ? split[1] : string.Empty;
Note that you should be using SQL command parameters to build the query string. The way you're doing it is vulnerable to SQL injection.
Also, as #Streamline mentioned, your original code has two if blocks instead of an if / else if. This means that both the if conditions will be evaluated regardless of which control triggered the event. It also means that if both ComboBoxes have a non-zero SelectedIndex, then both the if block bodies will run. This may be a cause for the error in the code from your question, and is not likely the intended behavior.
Finally, as #OlivierJacot-Descombes mentioned, if no item is selected then SelectedIndex will be -1, not 0. This means that when you check for comboBox1.SelectedIndex!=0, not only are you ignoring the value in the first (0) position, but if no value is selected, then it will pass this condition (because the value in that case is -1).
Is it possible to populate a combobox in c# with data from a datagridview which is linked to a Microsoft Access database & if not an existing record populate it with a selection based on the access dataview lookup data selections. I would like to be able to populate all of the text boxes & combo boxes if i select the record in the datagridview & if it is not yet a record i want to be able to select an option from the Combo Box pulldown in order to save the data to the database. I also want the datagrid to start with the first id which i think i have to do with the sql statement & i also do not want duplicate items in the pull down as you see in my state selection Combo Box. This Combo Box is based on the column data so all of the different records with the same data shows up in the Combo Box. Here is a bit of the code:
private void WendysForm_Load(object sender, EventArgs e)
{
try
{
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
// + values('" txt_ID.Text + "', ' "txt_Nickname.Text + '")
string query =
"select * from Wendys";
command.CommandText = query;
OleDbDataReader reader= command.ExecuteReader();
while(reader.Read())
{
cb_State.Items.Add(reader["State"].ToString());
cb_AssetType.Items.Add(reader["AssetType"].ToString());
cb_BaseModel.Items.Add(reader["BaseModel"].ToString());
cb_BldgPrototypeYear.Items.Add(reader["BldgPrototypeYear"].ToString());
cb_UpgradeClass.Items.Add(reader["UpgradeClass"].ToString());
cb_ExtWallStructure.Items.Add(reader["ExtWallStructure"].ToString());
cb_NewWallStructure.Items.Add(reader["NewWallStructure"].ToString());
cb_ExtRoofStructure.Items.Add(reader["ExtRoofStructure"].ToString());
cb_NewRoofStructure.Items.Add(reader["NewRoofStructure"].ToString());
cb_ExtFndType.Items.Add(reader["ExstFoundationType"].ToString());
cb_NewFndType.Items.Add(reader["NewFoundationType"].ToString());
cb_Addition.Items.Add(reader["Addition"].ToString());
cb_BladeDesign.Items.Add(reader["BladeDesign"].ToString());
cb_DriveThruType.Items.Add(reader["DriveThruType"].ToString());
cb_Patio.Items.Add(reader["Patio"].ToString());
cb_TrashEnclosure.Items.Add(reader["TrashEnclosure"].ToString());
cb_CounterStyle.Items.Add(reader["CounterStyle"].ToString());
cb_SelfServe.Items.Add(reader["SelfServe"].ToString());
cb_MenuboardType.Items.Add(reader["DigitalStatic"].ToString());
cb_RaisedCeiling.Items.Add(reader["RaisedCeiling"].ToString());
list_Notes.Items.Add(reader["Notes"].ToString());
}
connection.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error " + ex);
}
}
Form View
I am using C# to create a Windows form application. How do I create a local database table to save the data described below? Currently my data table consists of the columns of "inv_Id", "Item_Id" and "quantity". I know I need to create the columns to store each of the data items below, but I do not know how to structure the table.
item={chair,table,pen, thumbdrive}
Price={5,10,2,48}
subtotal
tax
total
I am new at C#. I did a search for this, and found things like e.g.https://www.youtube.com/watch?v=I5qvyyhUKfY
The data is shown in a list box and looks like:
Ordered Item:chair Price:$5.00
Ordered Item:table Price:$10.00
Ordered Item:pen Price:$2.00
Ordered Item:thumbdrive Price:$48.00
Subtotal:$65.00 Tax:$3.90 Total:$68.90
The purpose for me is to create the invoice then save it in the database after calculating everything.
Here is the code that I get the data load the data from db into drop down list (for user to select which item they want to buy), then (cust selected item will be listed in the listOuput box for calculating) user will select the item, then list box will show the selected output and calculate the total like a receipt.
After calculating, I wish to store all the data at the listOutput box to my db, but I having problem here.
Problem: I do not know how to move all my data from list box to
database, and link them together in the structure.
public partial class Select_Item : Form
{
SqlConnection con = new SqlConnection( #"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\oo\Documents\Data.mdf;Integrated Security=True;Connect Timeout=30");
SqlDataAdapter da = new SqlDataAdapter();
DataTable dt = new DataTable();
public struct Orders
{
public string item;
public double price;
}
const double TAX=0.06;
Orders order = new Orders();
static double subtotal=0;
static double totalTaxes=0;
static double total;
string finalBill = "FINAL BILL: \n";
public Select_Item()
{
InitializeComponent();
}
private void getValues(string custOrder)
{
order.item = custOrder;
String a = comboBox1.Text;
order.price = Convert.ToDouble(custOrder);
listOutput.Items.Add("Price: " + order.price);
finalBill += "Ordered Item: " + a + "\nPrice: " + order.price.ToString("C2") + "\n";
updateBill();
}
private void updateBill()
{
subtotal += order.price;
total += order.price + (order.price * TAX);
totalTaxes += order.price * TAX;
listOutput.Items.Clear();
listOutput.Items.AddRange(finalBill.Split('\n'));
listOutput.Items.Add("Subtotal:" + subtotal.ToString("C2"));
listOutput.Items.Add("Tax:" + totalTaxes.ToString("C2"));
listOutput.Items.Add("Total:" + total.ToString("C2"));
}
private void dropdownSelection(object sender, EventArgs e)
{
if (sender == comboBox1)
System.Diagnostics.Debug.WriteLine("test " + comboBox1.SelectedValue.ToString());
getValues(comboBox1.SelectedValue.ToString());
}
Edited Code:
private void StoreData()
{
int invoiceID;
using (var con1 = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\choo\Documents\Data.mdf;Integrated Security=True;Connect Timeout=30"))
{
con.Close();
con.Open();
using (var cmd = con.CreateCommand())
{
cmd.CommandText = #"insert into Invoice(subtotal,tax,total) values (#subtotal,#tax,#total); select SCOPE_IDENTITY() as InvoiceID;";
cmd.Parameters.AddWithValue("#subtotal", subtotal);
cmd.Parameters.AddWithValue("#tax", tax);
cmd.Parameters.AddWithValue("#total", total);
using (var reader = cmd.ExecuteReader())
{
if (reader.Read())
invoiceID = (int)reader["InvoiceID"];
}
}
foreach (var item in OrderItems.Rows)
{
using (var cmd = con.CreateCommand())
{
cmd.CommandText = #"insert into InvoiceItem(invoiceID,Item_Id,quantity) values (#invoiceID,#Item_Id,#quantity);";
// cmd.Parameters.AddWithValue("#InvoiceID", invoiceID);
cmd.Parameters.AddWithValue("#invoiceID", Convert.ToInt32("invoiceID"));
cmd.Parameters.AddWithValue("#Item_Id", Convert.ToInt32("Item_Id"));
cmd.Parameters.AddWithValue("#quantity", Convert.ToInt32("quantity"));
cmd.ExecuteNonQuery();
}
}
}
}
I am assuming you are saving the data to an SQL database. Your invoice and item tables share a many to many relationship, so you should use a third table to link them together.
Invoice: invoiceID, subtotal, tax, total
Item: itemID, price
InvoiceItem: invoiceItemID, invoiceID, itemID, quantity
The InvoiceItem table has foreign keys to the other two. This way you keep your invoice and item data separate and clean; there's no mucking about with 10 different "pen" items because 10 different orders included a pen.
Note that you can calculate Invoice.subtotal by selecting all the items from that invoice and calculating the sum of quantity * price. I recommend including it on the Invoice table for convenience's sake.
To get the order into the database, you want something like this:
private void StoreData()
{
int invoiceID;
using(var con = new SqlConnection( #"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\oo\Documents\Data.mdf;Integrated Security=True;Connect Timeout=30"))
{
con.Open();
using(var cmd = con.CreateCommand())
{
cmd.CommandText = #"insert into Invoice(subtotal,tax,total) values (#subtotal,#tax,#total); select SCOPE_IDENTITY() as InvoiceID;";
cmd.Parameters.AddWithValue("#subtotal",subtotal);
cmd.Parameters.AddWithValue("#tax",tax);
cmd.Parameters.AddWithValue("#total",total);
using(var reader = cmd.ExecuteReader())
{
if(reader.Read())
invoiceID = cmd.GetInt32("InvoiceID");
}
}
foreach(var item in orderItems)
{
using(var cmd = con.CreateCommand())
{
cmd.CommandText = #"insert into InvoiceItem(InvoiceID,ItemID,quantity) values (#InvoiceID,#ItemID,#quantity);";
cmd.Parameters.AddWithValue("#InvoiceID",invoiceID);
cmd.Parameters.AddWithValue("#ItemID",item.ItemID);
cmd.Parameters.AddWithValue("#quantity",item.Quantity);
cmd.ExecuteNonQuery();
}
}
}
}
Please understand this is a rudimentary, bare-bones idea of what you need to do. I've also written it without actually checking it in an IDE, so there might be a mistake or two. Importantly, it's not compatible with your existing code. Here's what you need to do to work this in:
Create a collection of items for your order, called orderItems. Each item in this collection should be some kind of object that represents a line in your ListBox. Note that your OrderItems struct is not sufficient to represent a single item (can you tell why?). Right now you're passing things around as strings of data. You need to be working with genuine objects to get a handle on the power of OOP.
Remove the SqlConnection declaration at the top of your form. You don't want connection objects just sitting around. The using blocks ensure a limited lifetime and that the object gets closed and disposed of properly. If you're using this object elsewhere (e.g. to get a list of items to show your user), then you need to modify that code to use this pattern.
Determining a good way to get itemID, subtotal, tax and total into this method. You could pass them as parameters, or you could use objects.
There are a lot of improvements that can be made, both to the code I've posted and to what you have already. This is meant only to be enough for basic functionality. Here are things that I leave to you as an exercise, but which you should do:
Error handling
Creating a proper collection of item objects and binding it to your UI elements
Getting static data like price and itemID from item objects and not out of the UI elements (ComboBox and ListBox)
Getting more familiar with the database interaction functionality, so you can understand how it works
I am working on sharp nlp where i am extracting all the adjective now i need to store this in database and i have successfully added this to database but the problem is with me that i want to store adjective separately to database how can i store the adjective separately or for example we have string and we want to store each word separately into database and we have only one column how can we do this? .please help me out
here is my code.
private void button2_Click(object sender, EventArgs e)
{
try
{
string cleaned = richTextBox1.Text.Trim();
string st = "INSERT INTO TABLE1(adjective)VALUES('" + cleaned + "')";
SqlConnection con = new SqlConnection("Data Source=ZAZIKHAN\\SQLEXPRESS;Initial Catalog=mis;Integrated Security=True");
con.Open();
SqlCommand cmd = new SqlCommand(st, con);
if (cmd.ExecuteNonQuery() == 1)
{
MessageBox.Show(" succesfully added");
}
else
{
MessageBox.Show("Sorry we couldnt add the Values Please try Again");
}
con.Close();
}
catch (Exception ex)
{
MessageBox.Show("" + ex);
}
}
now i have this data to be stored which is in richtextbox.
local/JJ daily/JJ n/price/rate/JJ human/JJ possible/JJ correct/JJ exact/JJ local/JJ
local/JJ daily/JJ n/price/rate/JJ human/JJ possible/JJ correct/JJ exact/JJ local/JJ
dry/JJ nd/JJ
new/JJ full/JJ OK/JJ final/JJ white/JJ OK/JJ howajaa/JJ smajder/JJR agaa/JJ nasambd/JJ Live/JJ
final/JJ
great/JJ s3/JJ final/JJ
resistant/JJ Z1/JJ white/JJ new/JJ black/JJ amaa.Kintact/JJ possible/JJ main/JJ mobile/JJ rapak/JJ mil/JJ
important/JJ mil/JJ smart/JJ
35-h/JJ OK/JJ full/JJ
Want/JJ complete/JJ white/JJ same/JJ
available/JJ perfect/JJ
interested/JJ
First off, the lines
string cleaned = richTextBox1.Text.Trim();
string st = "INSERT INTO TABLE1(adjective)VALUES('" + cleaned + "')";
create a massive security hole known as SQL Injection.
In order to store the adjectives separately in a properly denormalized database, you would have a parent table where e.g. the original sentence is stored, and a child table with a 1:N relationship to the parent where you store one row per adjective plus the appropriate ID of the parent row.
Since you only have one column available, you can use any convenient format to store the array of adjectives in a single column. You could serialize that array (to Binary, XML, JSON, etc) and store it, or since you know you have a limited input character set, you could even store it as a comma separated list.
You can prefix your words with some characters to indicate whether they are verb , noun , adjective and tehn insert those value in database
eg
N_JonSkeet - Noun
V_Solve - Verb
A_Highest - Adjective
string cleaned = extractAdjective(richTextBox1.Text.Trim());
string st = "INSERT INTO TABLE1(word) VALUES(#Word)";
SqlConnection con = new SqlConnection("Data Source=ZAZIKHAN\\SQLEXPRESS;Initial Catalog=mis;Integrated Security=True");
con.Open();
SqlCommand cmd = new SqlCommand(st, con);
SqlParameter param = new SqlParameter("#Word", SqlDbType.NChar);
param.Value = "A_"+cleaned;
cmd.Parameters.Add(param);
I would separate the string into a list and then iterate over the list and insert into your DB:
var vals = "local/JJ daily/JJ n/price/rate/JJ human/JJ possible/JJ...";
var results = vals.Replace(" ", "")
.Replace("/JJ", "|")
.Replace("/", "|")
.Split('|')
.Distinct();
while(var result in results)
{
// DO insert here
}
I have a DataGridView(DGV) linked to a SQlite database. I want to update some info on the DGV. So, I have a context menu that lets me change one column and update the DB as well. I want to have the ability to select multiple rows and edit as well. For ex: if i select five rows and change the type from alarms to errors ; the change is reflected in the DGV and then when i look into the database , the change isnt reflected. Only one row is updated.
My code snippet is below
foreach (DataGridViewRow r in dataGridView1.SelectedRows)
{
SQLiteTransaction SQLiteTrans = connection.BeginTransaction();
SQLiteCommand cmd = connection.CreateCommand();
MessageBox.Show(r.ToString());
if (r.Cells["typeDataGridViewTextBoxColumn"].Value.ToString().Contains("#") == false)
{
r.Cells["typeDataGridViewTextBoxColumn"].Value = r.Cells["typeDataGridViewTextBoxColumn"].Value.ToString() + " # " + max;
}
else
{
r.Cells["typeDataGridViewTextBoxColumn"].Value = r.Cells["typeDataGridViewTextBoxColumn"].Value.ToString().Substring(0, r.Cells["typeDataGridViewTextBoxColumn"].Value.ToString().IndexOf("#")) + "# " + max;
}
string querytext = "Update LogDatabase set Type = \"" + r.Cells["typeDataGridViewTextBoxColumn"].Value + "\" where HashKey = \"" + r.Cells["hashKeyDataGridViewTextBoxColumn"].Value.ToString() + "\"";
cmd.CommandText = querytext;
cmd.ExecuteNonQuery();
SQLiteTrans.Commit();
}
I dont have too much experience with SQL. So, im not sure if something is wrong with how ive updated the database!
What do i have to edit to make sure all the rows are updated in the DB as well?!
Help appreciated.
Edit: Tried checking the query before its sent.
When i try editing multiple rows in the DGV without sorting the DGV under any column it works and updates all the rows simultaneously... But When I try to sort them based on "Type" and then edit the rows, the same query is passed ! :| (Hash Key doesnt change)
Its like, the one row keeps moving up the list of rows and is always the row r in the for loop.
Edit 2: Its definitely a problem with the rows of the DGV
Everytime I sort the DGV and then try to edit the fields, the queries have hashkey values different from the once that i selected. Its like the row ids are changed completely after one update. It looks like the DGV automatically sorts once one row is updated !
Is there a way to disable this???!
It looks like you weren't increasing max counter.
foreach (DataGridViewRow row in dataGridView1.SelectedRows)
{
using (SQLiteTransaction SQLiteTrans = connection.BeginTransaction())
{
SQLiteCommand cmd = connection.CreateCommand();
MessageBox.Show(row.ToString());
var txtValue = row.Cells["typeDataGridViewTextBoxColumn"].Value;
if (txtValue.Contains("#"))
{
txtValue = String.Format("{0} # {1}", txtValue, max);
}else
{
txtValue = txtValue.SubString(0, txtValue.IndexOf("#")) + "# " + max.ToString();
}
string querytext = "Update LogDatabase set Type = #type where HashKey = #key";
//Create your SqlParameters here!
cmd.CommandText = querytext;
cmd.ExecuteNonQuery();
SQLiteTrans.Commit();
max++; //You weren't increasing your counter!!
}
}
Your problem is that you are using double quotes in your SQL query to delimit your string values. Replace them for single quotes:
string querytext = "Update LogDatabase set Type = '" +
r.Cells["typeDataGridViewTextBoxColumn"].Value +
"' where HashKey = '" +
r.Cells["hashKeyDataGridViewTextBoxColumn"].Value.ToString() +
"'";
Also, beware of SQL Injection. Your code is not dealing with that.