How to know when SQL query has finished - c#

I´m trying to create a logic to update massively the column "Prices" from table "Products".
This logic is made, but in my C# code I send the command to the MS Access DB, and immediately I want to show the new results.
The problem is that the update query takes a few seconds to finish, and my C# instantaneously asks for the Select from Products, showing no changes.
The main question is how I can know when the update has finished to show the new results in the grid.
Here my code:
private void btnAceptar_Click(object sender, EventArgs e)
{
string operator;
int code = Convert.ToInt32(cmbcode .SelectedValue);
int material = Convert.ToInt32(cmbMaterial.SelectedValue);
int productType= Convert.ToInt32(cmbproductType.SelectedValue);
if (cmboperating.SelectedIndex == 0){ operator= "+"; }
else if (cmboperating.SelectedIndex == 1) { operator= "-"; }
else if (cmboperating.SelectedIndex == 2) { operator= "*"; }
else { operator= "/"; }
if(txtValoroperating.Text != "") { txtValoroperating.Text = (txtValoroperating.Text).Replace(",", "."); }
string operating = txtValoroperating.Text;
if(rdPrecioDeLista.Checked == true & cbTodasPiezas.Checked == true)
{
//Here is my problem
oProductsDAL.modifyPricesMassively(operating, operator);
txtValoroperating.Text = null;
fillGridProducts();
}
}
And oProductsDAL.modifyPricesMassively(operating, operator) does this:
public bool modifyPricesMassively(operating, operator)
{
if (operating!= "" & operator!= "")
{
return conexion.executeMethod("UPDATE Piezas SET Precio = Precio " +operator+" " +operating);
}
else
{
return false;
}
}
conexion.executeMethod does this:
public bool conexion.executeMethod(string strComando)
{
try
{
OleDbCommand Comando = new OleDbCommand();
Comando.CommandText = strComando;
Comando.Connection = this.establecerConexion();
Conexion.Open();
Comando.ExecuteNonQuery();
Conexion.Close();
return true;
}
catch (Exception ex)
{
MessageBox.Show("No se pudo establecer conexion con la base de datos" +ex);
return false;
}
}
I wish to show a progress bar or a gif loading icon.

Related

Processing data in datagridview became very slow

So I have this program I made a couple of years ago that helps me process and correct data I have for my work. I run it once an year and forget about it till the next year.
I have a big data file (usually over 800k+ rows and 5 columns) that have to go through various checks for data correctness. I bind the file via an excel spreadsheet into the datagridview like this:
public DataTable ReadExcel(string fileName, string fileExt)
{
string conn = string.Empty;
DataTable dtexcel = new DataTable();
if (fileExt.CompareTo(".xlsx") == 0)
{
conn = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties='Excel 12.0;HDR=NO';"; //for above excel 2007
}
using (OleDbConnection con = new OleDbConnection(conn))
{
try
{
OleDbDataAdapter oleAdpt = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", con); //here we read data from sheet1
oleAdpt.Fill(dtexcel); //fill excel data into dataTable
}
catch { }
}
return dtexcel;
}
Also I load the file using this:
private void loadExcelTable_Click(object sender, EventArgs e)
{
string filePath = string.Empty;
string fileExt = string.Empty;
OpenFileDialog file = new OpenFileDialog(); //open dialog to choose file
if (file.ShowDialog() == DialogResult.OK) //if there is a file choosen by the user
{
filePath = file.FileName; //get the path of the file
fileExt = System.IO.Path.GetExtension(filePath); //get the file extension
textBox1.Text = filePath; //display the path to the file in the loadFile text box
if (fileExt.CompareTo(".xls") == 0 || fileExt.CompareTo(".xlsx") == 0)
{
try
{
this.Cursor = Cursors.WaitCursor;
phoneGridView1.VirtualMode = true;
phoneGridView1.Visible = true;
phoneGridView1.DataSource = ReadExcel(filePath, fileExt);
this.Cursor = Cursors.Default;
MessageBox.Show("Файлът зареден успешно!", "Success!", MessageBoxButtons.OK); //custom message for successful file loading
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
else
{
MessageBox.Show("Моля изберете .xlsx файл.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Error); //custom messageBox to show error
}
}
}
After everything is loaded, I press the button and various checks on the data start happening internally (lots of ifs involved).
Last year when I did this, everything went smoothly and the checks went out for about 3h on the whole file. THIS YEAR something changed. I dont know if it is from some VS2019 update or something, but the internal checks were taking way way way more time. I let the file sit for a whole week and it didnt even check half of it.
My questions are: is there a way to get things working as before? Did some update during that year changed the way the datagridview processes data?
I didnt do any changes to the code between my last working and now. The only thing that was changed was that I changed my GPU, but I dont believe this can cause such a huge drop in performance (I upgraded, no downgraded).
Any kind of help with this issue will be much appreciated.
Sample code of internal checks for data validation:
private void checkEmail(string email, int i)
{
//counts the symbols after the # symbol
string afterSymbol = email.Substring(email.LastIndexOf('#') + 1);
int lenght = afterSymbol.Length;
if (email.Contains("#") && email.Contains(".") && lenght >= 5)
{
phoneGridView1.Rows[i].Cells[4].Value = "01";
}
else
{
phoneGridView1.Rows[i].Cells[4].Value = "02";
}
phoneGridView1.Update();
}
Button_click function: All functions that are called here consists of various segments like the code segment above that checks the data in the datagridview
private void checks_Click(object sender, EventArgs e)
{
if (phoneGridView1.Rows.Count != 0)
{
int maxRows = phoneGridView1.RowCount;
int maxColumns = phoneGridView1.ColumnCount;
string fieldValue;
DataTable Codes1 = Codes(textBox2.Text);
Codes1.PrimaryKey = new DataColumn[] { Codes1.Columns["Column1"] };
this.Cursor = Cursors.WaitCursor;
if (Codes1.Rows.Count >0)
{
//Check each row if it contains one of the appointed values
for (int i = 1; i < maxRows; i++)
{
fieldValue = phoneGridView1.Rows[i].Cells[3].Value.ToString();
//Checks if the value in the row is the email
if (phoneGridView1.Rows[i].Cells[2].Value.ToString() == "3")
{
checkEmail(fieldValue, i);
}
//Checks if the value in the row is GSM number
if (phoneGridView1.Rows[i].Cells[2].Value.ToString() == "5")
{
checkGSM(fieldValue, i);
}
//Check if the telephone number is correct
if (phoneGridView1.Rows[i].Cells[2].Value.ToString() == "1")
{
checkTelephone(fieldValue, i, Codes1);
}
//Check if the fax number is correct
if (phoneGridView1.Rows[i].Cells[2].Value.ToString() == "2")
{
checkFax(fieldValue, i, Codes1);
}
//Check if the web page is correct
if (phoneGridView1.Rows[i].Cells[2].Value.ToString() == "6")
{
checkWeb(fieldValue, i);
}
if (phoneGridView1.Rows[i].Cells[4].Value.ToString() == string.Empty)
{
phoneGridView1.Rows[i].Cells[4].Value = "19";
}
}
this.Cursor = Cursors.Default;
MessageBox.Show("Успешно проверени данни!", "Success!", MessageBoxButtons.OK);
}
else
{
MessageBox.Show("Моля въведете файл със кодовете на населените места!", "Error!", MessageBoxButtons.OK);
}
}
else
{
MessageBox.Show("Моля въведете файл за проверка!", "Error!", MessageBoxButtons.OK);
}
}

c# BeginInvoke doesn't work

I have this code
private delegate void InvokeDelegate();
private void OpenFormNewNote(object sender, FileSystemEventArgs e)
{
if(loop == 2)
{
string service = null;
if (currentServiceName != null)
{
service = currentServiceName.Replace(" ", "");
}
NewNotePanel newNote = new NewNotePanel(e.FullPath, service, listOfService, Path, MyConn, ipAddress, imgFolder, Utente_id);
newNote.TopMost = true;
watcher.EnableRaisingEvents = false;
var result = newNote.ShowDialog();
if(result == DialogResult.OK || result == DialogResult.Cancel)
{
watcher.EnableRaisingEvents = true;
if(result == DialogResult.OK)
{
this.BeginInvoke(new InvokeDelegate(Refresh));
}
}
loop = 0;
}
else
{
loop++;
}
}
And this is the Refresh() Function:
public void Refresh()
{
noteContainer.Controls.Clear();
page = 0;
try
{
string Query = "SELECT a, v, b, cFROM note Where Servizio_ID = " + asd+ " AND Visibile = 1 order by ID desc limit 15 OFFSET " + (pageIndex * page) + " ;";
MySqlCommand MyCommand = new MySqlCommand(Query, MyConn);
MySqlDataReader MyReader;
if (MyConn.State == ConnectionState.Open)
{
MyReader = MyCommand.ExecuteReader();// Here our query will be executed and data saved into the database.
while (MyReader.Read())
{
CreateNotePreview(MyReader.GetString("a"), MyReader.GetString("b"), MyReader.GetString("c"), MyReader.GetString("d"));
}
MyReader.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Since OpenFormNewNote is called when the "Change" event of FileSystemWatcher is triggered.. of course it runs on a separated thread. Instead Refresh() does some UI stuff and it can't be called directly from OpenFormNewNote() otherwise it gives a Cross-Thread exception. So I tried with delegate but when the codeflow arrives on the BeginInvoke part.. Nothing happens and the Refresh function is not called.
What should I do?

Serializing Aysnchronous SQLCommand

I have the code below which works fine when the Session state is InProc. However when the Session state is Sql Server, HandleCallback never gets called. How do I change the code so HandleCallBack gets called?
private void TAdata(object sender, EventArgs e)
{
if (((Form)sender).DialogResult == DialogResult.No)
{
return;
}
if (Changed)
{
MessageBox.Show(this.ParentForm, "Save Payroll Changes First", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
else
{
SqlConnection dbconnAS = new SqlConnection(strDBconnAS);
{
try
{
AsyncCallback callback = new AsyncCallback(HandleCallback);
using (SqlCommand SQLcmd = new SqlCommand("dbo.KronosTaData", dbconnAS))
{
SQLcmd.CommandType = CommandType.StoredProcedure;
dbconnAS.Open();
Changed = true;
SQLcmd.BeginExecuteNonQuery(callback, SQLcmd);
strResult = "";
ExportProgress.Visible = true;
ExportProgress.Value = 0;
ExportProgress.Maximum = 120;
ExportTimer.Start();
}
}
catch (Exception ex)
{
Changed = false;
strResult = ex.Message;
if (dbconnAS != null)
{
dbconnAS.Close();
}
}
}
}
}
private void HandleCallback(IAsyncResult result)
{
try
{
using (SqlCommand SQLcmd = (SqlCommand)result.AsyncState)
{
int rowCount = SQLcmd.EndExecuteNonQuery(result);
strResult = "OK";
SQLcmd.Connection.Close();
}
}
catch (Exception ex)
{
strResult = ex.Message;
}
}
private void ExportTimer_Tick(object sender, EventArgs e)
{
//Timer Exists on UI thread
if (strResult == "")
{
if (cmdKronos.Enabled) cmdKronos.Enabled = false;
if (ExportProgress.Value > ExportProgress.Maximum - 10) ExportProgress.Maximum += 10;
ExportProgress.Value += 1;
}
else if (strResult == "OK")
{
Changed = false;
cmdKronos.Enabled = true;
ExportProgress.Visible = false;
ExportTimer.Stop();
MessageBox.Show(ParentForm, "Kronos data succesfully imported", "Data Import", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
Changed = false;
cmdKronos.Enabled = true;
ExportProgress.Visible = false;
ExportTimer.Stop();
MessageBox.Show(ParentForm, Text, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
You are disposing the command as soon as you've finished starting it:
using (SqlCommand SQLcmd = new SqlCommand("dbo.KronosTaData", dbconnAS))
{
//...
SQLcmd.BeginExecuteNonQuery(callback, SQLcmd);
//...
}
that will abort everything - so indeed: it will never complete. Basically; using doesn't play nicely with Begin*/End*, so don't do that. You might find it much easier to do this using async/await, by the way (via ExecuteNonQueryAsync).
You also probably want to close and dispose the connection somewhere; again, async/await would make this much easier to get right.
The solution is to declare the variable strResult as static.
See Visual Webgui Variable Scope

Search a record before saving it

I'm developing a simple inventory program that store the hardware devices using C# sql
In my program before I save the record, I want to search for serial number if it exist before I save it or add it in my records to avoid the duplicate, and I receive this exception error:
Syntax error: Missing operand after 'No' operator
Below is my code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Data.SqlServerCe;
namespace DataBaseApplication
{
public partial class Form1 : Form
{
#region Fields
SqlDataAdapter dataAdapter;
DataSet ds;
// DataRowView drView;
CurrencyManager crmng;
SqlConnection con;
ToolTip tootip;
int inc = 0;
#endregion
public Form1()
{
InitializeComponent();
}
#region Connetion to the DataBase and fill the DataSet Table
private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'impiDbDataSet1.Impi' table. You can move, or remove it, as needed.
//this.impiTableAdapter1.Fill(this.impiDbDataSet1.Impi);
// TODO: This line of code loads data into the 'impiDbDataSet.Impi' table. You can move, or remove it, as needed.
//this.impiTableAdapter.Fill(this.impiDbDataSet.Impi);
try
{
string conStrings = #"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\ImpiDb.mdf;Integrated Security=True;Connect Timeout=30";
string sql = "Select * from Impi";
con = new SqlConnection(conStrings);
con.Open();
dataAdapter = new SqlDataAdapter(sql, con);
ds = new DataSet();
dataAdapter.Fill(ds, "Impi");
impdg.DataSource = ds.Tables["Impi"].DefaultView;
crmng = (CurrencyManager)impdg.BindingContext[ds.Tables[0]];
tootip = new ToolTip();
con.Close();
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
}
#endregion
#region Save the Records to the DataBase
private void btnSave_Click(object sender, EventArgs e)
{
try
{
System.Data.SqlClient.SqlCommandBuilder cb;
cb = new System.Data.SqlClient.SqlCommandBuilder(dataAdapter);
// cb.DataAdapter.Update(ds.Tables["Impi"]);
DataRow dr = ds.Tables["Impi"].NewRow();
dr[0] = txtSerial.Text;
if (txtName.Text != "")
{
dr[1] = txtName.Text;
//Busy trying to solve exception errors and saving the record functionality without duplicating primary key
}
if (cbModel.Text == "MK1" || cbModel.Text == "MK2")
{
dr[2] = cbModel.Text;
}
if (cbStatus.Text == "Serviceble" || cbStatus.Text == "Unserviceble")
{
dr[3] = cbStatus.Text;
}
if (cbDeprtmnt.Text == "AIR" || cbDeprtmnt.Text == "LAND" || cbDeprtmnt.Text == "NAVY" || cbDeprtmnt.Text == "SPECIAL FORCE")
{
dr[4] = cbDeprtmnt.Text;
}
// ds.Tables["Impi"].Rows.Add(dr);
//This is where i stopped trying to figure out how to save my records properly
if (txtSerial.Text.Length!=0)
{
bool search = SearchSerialNumberBeforeSave(txtSerial.Text);
if (search == false)
{
DialogResult dr2 = MessageBox.Show("Are you sure you want to save this serial number", "Message", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (dr2 == DialogResult.Yes)
{
ds.Tables["Impi"].Rows.Add(dr);
dataAdapter.Update(ds, "Impi");
MessageBox.Show("Serial Number Added Successful");
}
// System.Data.SqlClient.SqlCommandBuilder cb;
//cb = new System.Data.SqlClient.SqlCommandBuilder(dataAdapter);
} //cb.DataAdapter.Update(ds.Tables["Impi"]);
else
{
MessageBox.Show("This Serial Number Exist and will create the duplicate.\nSerial Number not Saved");
MessageBox.Show("Data Entry was not saved", "Sorry", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
MessageBox.Show("Please Enter a Impi Serial Number","Data Entry");
txtSerial.Text = "Please Enter Impi Serial Number";
txtSerial.ForeColor = Color.Red;
tootip.SetToolTip(txtSerial, txtSerial.Text);
}
// crmng.Position += 1;
// inc = crmng.Position - 1;
// btnAdd.Enabled = true;
// btnSave.Enabled = false;
if (txtName.Text.Length==0)
{
txtName.Text = "Please Enter the Track Number";
txtName.ForeColor = Color.Red;
tootip.SetToolTip(txtName, txtName.Text);
}
if (cbModel.Text.Length == 0)
{
cbModel.Text = "Please Select the Model Of the device";
cbModel.ForeColor = Color.Red;
tootip.SetToolTip(cbModel, cbModel.Text);
}
if (cbStatus.Text.Length == 0)
{
cbStatus.Text = "Please Select the status of the device";
cbStatus.ForeColor = Color.Red;
tootip.SetToolTip(cbStatus, cbStatus.Text);
}
if (cbDeprtmnt.Text.Length == 0)
{
cbDeprtmnt.Text = "Please Select the assigned department";
cbDeprtmnt.ForeColor = Color.Red;
}
else
{
MessageBox.Show("Data Entry was not Saved", "Sorry", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
con.Close();
}
#endregion
#region Search Method
public bool SearchSerialNumberBeforeSave(String name)
{
int result = 0;
DataRow[] retRows;
bool val;
//This line of code give this exception error Syntax error: Missing operand after 'No' operator.
retRows = ds.Tables["Impi"].Select("Serial No='" + name + "'");
result = retRows.Length;
if (result > 0)
{
val = true;
}
else
{
val = false;
}
return val;
}
#endregion
}
}
The space in Serial Nois causing this issue.
In order to solve it replace Serial No with [Serial No]
retRows = ds.Tables["Impi"].Select("[Serial No]='" + name + "'");
Take a look at this thread, It asks about the same issue.

textbox and dropdown values inserted should store in database using c# asp.net

I got a tab container which has 4 tabs in it. In one of the tab named ADD TASK I got few fields like
(Task Name: --txtbox
Client Name:--drpdwn
Begin Date:--txtbox wid calendar
Due Date:--txtbox wid calendar
Description:--txtbox
Assign To:--drpdown
Status:--drpdown
% Complete:--drpdown)
and an ADD and CANCEL button in the end.
On running the project and inserting the values to those above mentioned fields i will click the add button and after clicking the button the values should store in my DATABASE. i have table named TASK in my DB already.
Please help me with the back end code.
here is my code
protected void BtnAdd_Click(object sender, EventArgs e)
{
MTMSDTO objc = new MTMSDTO();
int Flag = 0;
objc.TaskName = Session["TaskName"].ToString();
objc.ClientName = DrpClientName.SelectedItem.Text;
objc.BeginDate = Convert.ToDateTime(TxtBeginDate.Text);
objc.DueDate = Convert.ToDateTime(TxtDueDate.Text);
objc.Description = Session["Description"].ToString();
objc.AssignTo = DrpAssignTo.SelectedItem.Text;
objc.Status = DrpStatus.SelectedItem.Text;
objc.PercentageComplete = Convert.ToInt32(DrpPercentageComplete.Text);
int X = obj.InsertTask(objc);
{
if (X >= 0)
{
Flag = 1;
}
else
{
Flag = 0;
}
}
if (Flag == 1)
{
LblSuccess.Visible = true;
LblSuccess.Text = "Data Added Successfully";
Panel2.Visible = false;
}
else
{
LblErr.Visible = true;
LblErr.Text = "Failed To Add Data!!!";
}
}
im using layered architecture and i have this code on my ACCESS file of DAL CLASS
public int InsertTask(MTMSDTO M)
{
DBAccess db = new DBAccess();
SqlParameter objParam = new SqlParameter("#TaskID", M.TaskID);
objParam.Direction = ParameterDirection.Output;
db.Parameters.Add(new SqlParameter("#TaskName", M.TaskName));
db.Parameters.Add(new SqlParameter("#ClientName", M.ClientName));
db.Parameters.Add(new SqlParameter("#BeginDate", M.BeginDate));
db.Parameters.Add(new SqlParameter("#DueDate", M.DueDate));
db.Parameters.Add(new SqlParameter("#Description", M.Description));
db.Parameters.Add(new SqlParameter("#AssignTo", M.AssignTo));
db.Parameters.Add(new SqlParameter("#Status", M.Status));
db.Parameters.Add(new SqlParameter("#PercentageComplete", M.PercentageComplete));
db.Parameters.Add(objParam);
int retval = db.ExecuteNonQuery("InsertTask");
if (retval >= 1)
{
return int.Parse(objParam.Value.ToString());
}
else
{
return -1;
}
}
the code is edited now but im getting error as "object reference not set to an instance of an object. " for the line (objc.TaskName = Session["TaskName"].ToString();) which is in BtnAdd_Cick.
Shouldn't your BtnAdd_Click function be something like this instead? You don't currently seem to be calling the InsertTask() function.
protected void BtnAdd_Click(object sender, EventArgs e) {
MTMSDTO m = new MTMSDTO();
m.TaskName = TxtTaskName.Text;
m.ClientName = DrpClientName.Text;
m.BeginDate = TxtBeginDate.Text;
m.DueDate = TxtDueDate.Text;
m.Description = TxtDescription.Text;
m.AssignTo = DrpAssignTo.Text;
m.Status = DrpStatus.Text;
m.PercentageComplete = DrpPercentageComplete.Text;
InsertTask(m);
}
get all values in back end and pass to this function
public bool InsertRecord(string strTableName, string strColumn_Name, string strValues)
{
SqlConnection OBJCONNECTION;
StringBuilder strbQuery;
SqlCommand cmd;
try
{
OBJCONNECTION= new SqlConnection();
OBJCONNECTION.ConnectionString = ConfigurationManager.ConnectionStrings["Basic_ADO"].ConnectionString;//get connection string from web.config file
OBJCONNECTION=
strbQuery = new StringBuilder();
strbQuery.Append("INSERT INTO ");
strbQuery.Append(strTableName);
strbQuery.Append("(" + strColumn_Name + ")");
//strbQuery.Append(" VALUES");
strbQuery.Append("(" + strValues + ")");
cmd = new SqlCommand(strbQuery.ToString(), OBJCONNECTION);
cmd.ExecuteNonQuery();
return true;
}
catch (Exception ex) { throw ex; }
finally { strbQuery = null; cmd = null;OBJCONNECTION.close();}
}

Categories

Resources