Can somebody help understand this code?
protected void Page_Load(object sender, EventArgs e)
{
Database database = new Database();
OleDbConnection conn = database.connectDatabase();
if (Request.Cookies["BesteldeArtikelen"] == null)
{
lbl_leeg.Text = "Er zijn nog geen bestelde artikelen";
}
else
{
HttpCookie best = Request.Cookies["BesteldeArtikelen"];
int aantal_bestel = best.Values.AllKeys.Length;
int[] bestelde = new int[aantal_bestel];
int index = 0;
foreach (string art_id in best.Values.AllKeys)
{
int aantalbesteld = int.Parse(aantalVoorArtikel(int.Parse(art_id)));
int artikel_id = int.Parse(art_id); // moet getalletje zijn
if (aantalbesteld != 0)
{
bestelde[index] = artikel_id;
}
index++;
}
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT artikel_id, naam, prijs, vegetarische FROM artikel WHERE artikel_id IN (" +
String.Join(", ", bestelde) + ")";
try
{
conn.Open();
OleDbDataReader reader = cmd.ExecuteReader();
GridView1.DataSource = reader;
GridView1.DataBind();
}
catch (Exception error)
{
errorMessage.Text = error.ToString();
}
finally
{
conn.Close();
}
}
}
And there is this part of code i dont really understand:
public string aantalVoorArtikel(object id)
{
int artikel_id = (int)id;
if (Request.Cookies["BesteldeArtikelen"] != null &&
Request.Cookies["BesteldeArtikelen"][artikel_id.ToString()] != null)
{
return Request.Cookies["BesteldeArtikelen"][artikel_id.ToString()];
}
else
{
return "0";
}
}
It extracts values from a cookie and builds an int array. (Displays a message if the cookie value is null) The int array is then used as the value for the SQL IN operator when querying the database. The result set is then bound to the GridView.
Related
In DataGridView I have two ComboBox columns:
private string controlFrom= "cmbMachineAndOpIDFrom";
private string controlTo = "cmbMachineAndOpIDTo";
I want to check those two-columns combination for duplicates. If duplicate exists or null the record must be cancelled with message for the user. I try to use RowValidating event for that:
private void dgvTransfers_RowValidating(object sender, DataGridViewCellCancelEventArgs e)
{
string columName = dgvTransfers.Columns[e.ColumnIndex].Name;
e.Cancel = IsDuplicateExists(columName);
}
The code of IsDuplicateExist:
private bool IsDuplicateExists(string colName)
{
bool res = false;
int existingRowID = 0;
if (colName.Equals(controlFrom) || colName.Equals(controlTo))
{
int cmbFrom = Convert.ToInt32(Helper.GetSelectedRowValueInDGV(dgvTransfers, controlFrom));
int cmbTo = Convert.ToInt32(Helper.GetSelectedRowValueInDGV(dgvTransfers, controlTo));
if (cmbFrom == 0 || cmbTo == 0)
{
res = true;
}
//Check for duplicates
existingRowID = Helper.GetDuplicatedRowIndex(cmbFrom, cmbTo, dgvTransfers, controlFrom, controlTo);
if (existingRowID > 0)
{
//Already exists
GoToDublicatedRecord(existingRowID, dgvTransfers);
res = true;
}
}
return res;
}
I always get 0 value for cmbFrom and cmbTo using method GetSelectedRowValueInDGV:
public static string GetSelectedRowValueInDGV(DataGridView dgvName, string columnName)
{
string res = "0";
if (dgvName.SelectedRows.Count > 0)
{
var vl = dgvName.SelectedRows[0].Cells[columnName].Value;
if (vl.ToString()!=string.Empty && vl != null && vl != DBNull.Value)
{
res = dgvName.SelectedRows[0].Cells[columnName].Value.ToString();
}
}
return res;
}
So first question is why I do not get selected cell value?
Here comes the second part of problem. Since both values are zeroes I get e.Cancel = true. Here I expect editing to be cancelled but instead I get error
'Operation did not succeed because the program cannot commit or quit a
cell value change.'
at row dgvName.DataSource = dt; in CellValueChanged event where GetDataForGridView is called to get data from SQL SP:
public static bool GetDataForGridView(DataGridView dgvName, string storedProcedureName, params SqlParameter[] arrParam)
{
DataTable dt = new DataTable();
bool result;
// Open the connection
using (SqlConnection sqlConn = new SqlConnection(strConn))
{
try
{
sqlConn.Open();
// Define the command
using (SqlCommand sqlCmd = new SqlCommand())
{
sqlCmd.Connection = sqlConn;
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.CommandText = storedProcedureName;
// Handle the parameters
if (arrParam != null)
{
foreach (SqlParameter param in arrParam)
{
sqlCmd.Parameters.Add(param);
}
}
// Define the data adapter and fill the dataset
using (SqlDataAdapter da = new SqlDataAdapter(sqlCmd))
{
da.Fill(dt);
result = true;
}
}
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
result = false;
}
dgvName.AutoGenerateColumns = false;
dgvName.DataSource = dt;
sqlConn.Close();
}
return result;
}
UPDATED
Here is how both Comboboxes are populated:
private void FrmTransfers_Load(object sender, EventArgs e)
{
Helper.GetDataForGridView(dgvTransfers, "pp_sp_Transfers", null);
PopCombo(cmbMachineAndOpIDFrom, "MachineAndOpID",0,0);
PopCombo(cmbMachineAndOpIDTo, "MachineAndOpID",0,0);
}
private void PopCombo(DataGridViewComboBoxColumn combo, string valMember, int parValue1, int parValue2)
{
DataTable dtMO = Helper.ExecuteDataTable("pp_sp_MachineAndOp",
new SqlParameter("#MachineAndOpID", SqlDbType.Int) { Value = parValue1 },
new SqlParameter("#Seq", SqlDbType.Int) { Value = parValue2 });
//Add field to be displayed
dtMO.Columns.Add("ToShow", typeof(string), "'Seq: ' + Seq + ' ID: ' + MachineAndOpID + ' (' + OperationID + ') ' + Operation + ' + ' + Machine");
// bind data table into combo box.
combo.DataSource = dtMO;
combo.DisplayMember = "ToShow";
combo.ValueMember = valMember;
}
after some testing I came with this way to handle my datagrid. dgVariedad_CellEditEnding use the function nombreVariedadDisponible(txtBoxTemporal.Text) to check if the new value already exist in List<Variedad> variedades and it works. The problem is that the value wont be inserted in the database but will be added in the datagrid control, I can't find a way to cancel the new row in the control.
private List<Variedad> variedades = new List<Variedad>();
private void bindVariedad()
{
using (MySqlCommand cmd = Conexion.con.CreateCommand())
{
cmd.CommandText = "SELECT NOMBRE FROM DATAFRUT_VARIEDADES WHERE ELIMINADO = 'F';";
Conexion.abrirConexion();
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
DataTable table = new DataTable("DATAFRUT_VARIEDADES");
da.Fill(table);
table.Columns[0].ColumnName = "Nombre";
dgVariedad.ItemsSource = table.DefaultView;
cmd.CommandText = "SELECT * FROM DATAFRUT_VARIEDADES WHERE ELIMINADO = 'F';";
using (MySqlDataReader dr = cmd.ExecuteReader())
{
variedades.Clear();
while (dr.Read())
{
Variedad var = new Variedad();
var.codigo = Convert.ToInt32(dr[0]);
var.nombre = dr[1].ToString();
var.eliminado = Convert.ToChar(dr[2]);
variedades.Add(var);
}
}
}
}
private void dgVariedad_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
TextBox txtBoxTemporal = e.EditingElement as TextBox;
int indice = e.Row.GetIndex();
if (e.Row.IsNewItem)
{
if (nombreVariedadDisponible(txtBoxTemporal.Text))
{
bool insertExitoso = false;
using (MySqlCommand cmd = Conexion.con.CreateCommand())
{
Conexion.abrirConexion();
cmd.CommandText = "INSERT INTO DATAFRUT_VARIEDADES VALUES (default, '" + txtBoxTemporal.Text + "', 'F');";
try
{
cmd.ExecuteNonQuery();
insertExitoso = true;
}
catch
{
MessageBox.Show("Error");
}
Conexion.cerrarConexion();
}
if (insertExitoso)
{
variedades.Add(Variedad.cargarUltimoInsert(txtBoxTemporal.Text));
}
}
else
{
e.Cancel = true;
}
}
else
{
using (MySqlCommand cmd = Conexion.con.CreateCommand())
{
Conexion.abrirConexion();
DataRowView dataRow = (DataRowView)dgVariedad.SelectedItem;
cmd.CommandText = "UPDATE DATAFRUT_VARIEDADES SET NOMBRE = '" + txtBoxTemporal.Text + "' WHERE CODIGO = " + variedades[dgVariedad.SelectedIndex].codigo + ";";
try
{
cmd.ExecuteNonQuery();
variedades[dgVariedad.SelectedIndex].nombre = txtBoxTemporal.Text;
}
catch(MySqlException mex)
{
MessageBox.Show("Error " + mex.Message);
}
Conexion.cerrarConexion();
}
}
}
My table on mysql has 3 fields:
int codigo (primary key, auto increment)
string Nombre (Unique) char
char Eliminado -> Eliminado (Deleted) with values (F = false and V =
true)
Here is how I check if the value already exist.
private bool nombreVariedadDisponible(string nombreAComparar)
{
//busca el nombre en la lista "variedades"
foreach (Variedad var in variedades)
{
if (var.nombre.ToLower() == nombreAComparar.ToLower() && var.eliminado == 'F')
return false;
}
return true;
}
My Class
public string Countryadd(string country, string id)
{
string data = "0";
try
{
string qry1 = "select Country from Country where Country='" + country + "'";//Checking weather txtcountry(Country Name) value is already exixst or not. If exist return 1 and not exists go to else condition
SqlDataReader dr = conn.query(qry1);
if (dr.Read())
{
return data = "1";
}
else
{
string qry = "insert into Country values('" + id + "','" + country + "')";
conn.nonquery(qry);
return data = "3";
}
}
catch (Exception ex)
{
string x = ex.Message();
}
return data;
}
this string value how can we set in a label
My button_click function is
protected void Button1_Click(object sender, EventArgs e)
{
string str = mas.Countryadd(txtcountry.Text, txtid.Text);
if (str == "1")
{
Response.Write("<script>alert('Country Already Exist!!!!')</script>");
}
else if (str == "3")
{
Response.Write("<script>alert('Country Added Succesfully')</script>");
}
else
{
Label1.Text = str;
}
}
It's not the prettiest of code. Returning a string as a kind of status code is generally bad practice, because you don't know the range of possible values which can be returned, and what they mean. At the very least consider integer or even enum (which is named).
That being said, I would handle the check and the insert in separate methods, and catch the exception in the click event handler - let a single method have a single responsibility:
private void AddCountry(string country, string id)
{
using (SqlConnection conn = new SqlConnection())
{
string sql = string.Format("INSERT INTO Country (Id, Country) VALUES ('{0}', '{1}')", id, country);
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.ExecuteNonQuery();
}
}
}
private bool Exists(string country, string id)
{
using (SqlConnection conn = new SqlConnection())
{
string sql = "SELECT Count(*) FROM Country WHERE Country='" + country + "'";
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
int count = (int)cmd.ExecuteScalar();
return count >= 1;
}
}
}
private void Button1_Click(object sender, EventArgs e)
{
try
{
if (Exists(txtcountry.Text, txtid.Text))
{
Response.Write("<script>alert('Country Already Exist!!!!')</script>");
}
else
{
AddCountry(txtcountry.Text, txtid.Text);
Response.Write("<script>alert('Country Added Succesfully')</script>");
}
}
catch (Exception ex)
{
Label1.Text = ex.Message;
}
}
Catch(Exception e)
{
Label.Text= e.Message;
}
I'm currently building a program which stores messages between users in a database and returns these messages to the user when the button below gets pressed. I'm using a SQL CE database using a OleDbConnection and using a DataReader.
private void button3_Click(object sender, EventArgs e)
{
string [] lec_name = new string [10] ;
string [] content = new string [10] ;
string conn = "Provider=Microsoft.SQLSERVER.CE.OLEDB.3.5;Data Source=C:\\Users\\Leon\\Admin.sdf";
OleDbConnection connection = new OleDbConnection(conn);
OleDbCommand command = connection.CreateCommand();
command.CommandText = "SELECT * FROM Contact_DB WHERE Student_ID =" + iD + " AND Direction = '" + "To the student" + "'";
try
{
connection.Open();
}
catch (Exception ex)
{
MessageBox.Show("" + ex.Message);
}
OleDbDataReader reader = command.ExecuteReader();
int up = 0;
int count = 0;
while (reader.Read())
{
lec_name[up] = reader["Lecturer_Name"].ToString();
content[up] = reader["Description"].ToString();
up++;
MessageBox.Show("The lecturer " + lec_name[count] + " has messaged you saying :" + "\n" + content[count]);
count++;
}
}
This code works for my Student class but when I reuse the code with minor changes within the Lecturer class the OledbDataReader says null, anyone know why?
Btw the values being returned aren't null the reader itself is null.
Below is the non working code.
private void button2_Click(object sender, EventArgs e)
{
string [] studentID = new string [10] ;
string [] content = new string [10] ;
string conn = "Provider=Microsoft.SQLSERVER.CE.OLEDB.3.5;Data Source=C:\\Users\\Leon\\Admin.sdf";
OleDbConnection connection = new OleDbConnection(conn);
OleDbCommand command = connection.CreateCommand();
command.CommandText = "SELECT * FROM Contact_DB WHERE Lecturer_Name =" + full + " AND Direction = '" + "To the lecturer" + "'";
try
{
connection.Open();
}
catch (Exception ex)
{
MessageBox.Show("" + ex.Message);
}
OleDbDataReader reader1 = command.ExecuteReader();
int up = 0;
int count = 0;
while (reader1.Read())
{
studentID[up] = reader1["Student_ID"].ToString();
content[up] = reader1["Description"].ToString();
up++;
}
MessageBox.Show("The student " + studentID[count] + " has messaged you saying :" + "\n" +content[count]);
}
}
Using Reflector:
OleDbCommand.ExcuteReader:
public OleDbDataReader ExecuteReader(CommandBehavior behavior)
{
OleDbDataReader reader;
IntPtr ptr;
OleDbConnection.ExecutePermission.Demand();
Bid.ScopeEnter(out ptr, "<oledb.OleDbCommand.ExecuteReader|API> %d#, behavior=%d{ds.CommandBehavior}\n", this.ObjectID, (int) behavior);
try
{
this._executeQuery = true;
reader = this.ExecuteReaderInternal(behavior, "ExecuteReader");
}
finally
{
Bid.ScopeLeave(ref ptr);
}
return reader;
}
The CommandBehavior is
default.the reader returned by this.ExecuteReaderInternal()---- >
private OleDbDataReader ExecuteReaderInternal(CommandBehavior behavior, string method)
{
OleDbDataReader dataReader = null;
OleDbException previous = null;
int num2 = 0;
try
{
object obj2;
int num;
this.ValidateConnectionAndTransaction(method);
if ((CommandBehavior.SingleRow & behavior) != CommandBehavior.Default) behavior |= CommandBehavior.SingleResult;
switch (this.CommandType)
{
case ((CommandType) 0):
case CommandType.Text:
case CommandType.StoredProcedure:
num = this.ExecuteCommand(behavior, out obj2);
break;
case CommandType.TableDirect:
num = this.ExecuteTableDirect(behavior, out obj2);
break;
default:
throw ADP.InvalidCommandType(this.CommandType);
}
if (this._executeQuery)
{
try
{
dataReader = new OleDbDataReader(this._connection, this, 0, this.commandBehavior);
switch (num)
{
case 0:
dataReader.InitializeIMultipleResults(obj2);
dataReader.NextResult();
break;
case 1:
dataReader.InitializeIRowset(obj2, ChapterHandle.DB_NULL_HCHAPTER, this._recordsAffected);
dataReader.BuildMetaInfo();
dataReader.HasRowsRead();
break;
case 2:
dataReader.InitializeIRow(obj2, this._recordsAffected);
dataReader.BuildMetaInfo();
break;
case 3:
if (!this._isPrepared) this.PrepareCommandText(2);
OleDbDataReader.GenerateSchemaTable(dataReader, this._icommandText, behavior);
break;
}
obj2 = null;
this._hasDataReader = true;
this._connection.AddWeakReference(dataReader, 2);
num2 = 1;
return dataReader;
}
finally
{
if (1 != num2)
{
this.canceling = true;
if (dataReader != null)
{
dataReader.Dispose();
dataReader = null;
}
}
}
}
try
{
if (num == 0)
{
UnsafeNativeMethods.IMultipleResults imultipleResults = (UnsafeNativeMethods.IMultipleResults) obj2;
previous = OleDbDataReader.NextResults(imultipleResults, this._connection, this, out this._recordsAffected);
}
}
finally
{
try
{
if (obj2 != null)
{
Marshal.ReleaseComObject(obj2);
obj2 = null;
}
this.CloseFromDataReader(this.ParameterBindings);
}
catch (Exception exception3)
{
if (!ADP.IsCatchableExceptionType(exception3)) throw;
if (previous == null) throw;
previous = new OleDbException(previous, exception3);
}
}
}
finally
{
try
{
if (dataReader == null && 1 != num2) this.ParameterCleanup();
}
catch (Exception exception2)
{
if (!ADP.IsCatchableExceptionType(exception2)) throw;
if (previous == null) throw;
previous = new OleDbException(previous, exception2);
}
if (previous != null) throw previous;
}
return dataReader;
}
this._executeQuery wraps the new instance of OleDbDataReader, if it doesn't run the dataReader will be null.
The only way the reader is returned as null is if the internal RunExecuteReader method is passed 'false' for returnStream, which it isn't.
Here is the only place where this._executeQuery is set to false, but this one is not called in parallel because of Bid.ScopeEnter and Bid.ScopeLeave.
public override int ExecuteNonQuery()
{
int num;
IntPtr ptr;
OleDbConnection.ExecutePermission.Demand();
Bid.ScopeEnter(out ptr, "<oledb.OleDbCommand.ExecuteNonQuery|API> %d#\n", this.ObjectID);
try
{
this._executeQuery = false;
this.ExecuteReaderInternal(CommandBehavior.Default, "ExecuteNonQuery");
num = ADP.IntPtrToInt32(this._recordsAffected);
}
finally
{
Bid.ScopeLeave(ref ptr);
}
return num;
}
Theoretically the data reader can be null if the query cannot be executed.
UPDATE:
https://github.com/Microsoft/referencesource/blob/master/System.Data/System/Data/OleDb/OleDbCommand.cs#L658
I want to make a library system in C#. In this system when a book is issued it should automatically reduce the book quantity in database. When book quantity == 0 there should be a message box showing "not available".
This is my code:
private void btnIssue_Click(object sender, EventArgs e)
{
if (cmbResID.Text != "" && cmbMemID.Text != "" && cmbBookID.Text != "" && txtBkTitle.Text != "" && txtCategory.Text != "" && txtAuthor.Text != "" && txtIssueDate.Text != "" && txtActDate.Text != "")
{
SqlCommand Quantity = new SqlCommand("Select * from tblBookDetails where Book_ID = '" + cmbBookID.Text +"'");
DataSet ds = Library.Select(Quantity);
if (ds.Tables[0].Rows.Count > 0)
{
textBox1.Text = ds.Tables[0].Rows[0].ItemArray.GetValue(5).ToString();
int b = Convert.ToInt32(textBox1.Text);
if (b > 0)
{
//a = a - 1;
//int b = Convert.ToInt32(a);
//label15.Text = a.ToString();
SqlCommand update=new SqlCommand("UPDATE tblBookDetails SET Quantity=Quantity-1 WHERE Book_ID='"+ cmbBookID +"'");
Library.ExecuteInsert(update);
SqlCommand save = new SqlCommand("insert into tblBookIssue values(#ResID,#Member_ID,#Book_ID,#Issue_Date,#Act_Ret_Date)");
save.Parameters.AddWithValue("#ResID", cmbResID.Text);
save.Parameters.AddWithValue("#Member_ID", cmbMemID.Text);
save.Parameters.AddWithValue("#Book_ID", cmbBookID.Text);
save.Parameters.AddWithValue("#Issue_Date", txtIssueDate.Text);
save.Parameters.AddWithValue("#Act_Ret_Date", txtActDate.Text);
Library.Insert(save);
MessageBox.Show("Book Issued", "Book Issue", MessageBoxButtons.OK, MessageBoxIcon.Information);
clear();
}
else
{
MessageBox.Show("this book is not available");
}
}
}
else
{
MessageBox.Show("FILL COLUMS");
}
}
Executing SQL based off of text boxes is very unsafe and Prone to SQL injection attacks. Also, to follow Object Oriented program and make much cleaner code it would be advisable to make a Book object, I completed some code below which shows an example including the book incrementer. It would be better to make focused stored procs which execute gets for books and updates for book checkouts. You will have to turn your basic select into a stored proc, and write another proc which looks at the quantity and if quantity < 1 return 0 else return 1. Let me know if you need more info, this code should help you get rolling
using System;
using System.Data;
using System.Data.SqlClient;
namespace MockLibrary
{
internal class Book
{
#region Constructors
public Book()
{
}
public Book(string resId, string memberId, string bookId, DateTime issueDate, DateTime actRetDate)
{
this.ResId = resId;
this.MemberId = memberId;
this.BookId = bookId;
this.IssueDate = issueDate;
this.ActRetDate = actRetDate;
}
#endregion
#region Properties
private string _ResID;
private string _MemberID;
private string _BookId;
private DateTime _IssueDate;
private DateTime _ActRetDate;
public string ResId
{
get { return _ResID; }
set { _ResID = value; }
}
public string MemberId
{
get { return _MemberID; }
set { _MemberID = value; }
}
public string BookId
{
get { return _BookId; }
set { _BookId = value; }
}
public DateTime IssueDate
{
get { return _IssueDate; }
set { _IssueDate = value; }
}
public DateTime ActRetDate
{
get { return _ActRetDate; }
set { _ActRetDate = value; }
}
#endregion
public Book GetBookByID(string resId, string memberId)
{
try
{
using (SqlConnection con = new SqlConnection("put your db con string here"))
{
using (SqlCommand cmd = new SqlCommand("sp_GetBookById", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#ResId", SqlDbType.VarChar).Value = resId;
cmd.Parameters.Add("#MemberId", SqlDbType.VarChar).Value = memberId;
con.Open();
cmd.ExecuteNonQuery();
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Book newBook = new Book(rdr["ResId"].ToString(),rdr["MemberId"].ToString(),rdr["BookId"].ToString(),DateTime.Now,DateTime.Now);
return newBook;
}
}
}
}
catch
{
throw new Exception("something went wrong");
}
return null;
}
public bool CheckoutBook(string resId, string memberId)
{
using (SqlConnection con = new SqlConnection("put your db con string here"))
{
using (SqlCommand cmd = new SqlCommand("sp_CheckoutBook", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#ResId", SqlDbType.VarChar).Value = resId;
cmd.Parameters.Add("#MemberId", SqlDbType.VarChar).Value = memberId;
con.Open();
cmd.ExecuteNonQuery();
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
if (rdr["checkoutsuccessful"].ToString() == "1")
{
return true;
}
}
}
}
return false;
}
}
}
when user returns a book:-
MySqlCommand cm1;
cm1 = new MySqlCommand("update addbook set bookquantity=bookquantity+1 where bookname='" + txt_bookname.Text + "'",con);
cm1.ExecuteNonQuery();