protected override void OnStart(string[] args)
{
try
{
t.Enabled = true;
t.Interval = 10000; //60 * 24;
t.Elapsed += new System.Timers.ElapsedEventHandler(t_Elapsed);
}
catch (Exception ex)
{
writeErrorToFile(ex.Message + " -- (OnStart) --");
}
}
this is my onstart method. I am new to making the windows service. Can you explain me what the code inside the instart method does.? I am not able to get the right answer when i googled.
Following is the method that is called from the onstart method
private void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
try
{
// Read Data from Excel
OleDbConnection conn = new OleDbConnection();
OleDbCommand cmd = new OleDbCommand();
OleDbDataAdapter da = new OleDbDataAdapter();
SqlCommand sm = new SqlCommand();
string connString = "";
string query = "";
string strDt = DateTime.Now.ToString("dd_MM_yyyy");
string strNewPath = #"E:\E-Cata_Stock_Report\ALL_INDIA_STOCK_REPORT_" + strDt + ".xls"; //Server.MapPath(#"C:\E-Cata_Stock_Report\ALL_INDIA_STOCK_REPORT.xls"); // ///" + strFileName + strFileType);
connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strNewPath +
";Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=2\"";
query = "SELECT * FROM [SPARE_LIST$]";
conn = new OleDbConnection(connString);
//Open connection
if (conn.State == ConnectionState.Open)
conn.Close();
conn.Open();
//Create the command object
cmd = new OleDbCommand(query, conn);
da = new OleDbDataAdapter(cmd);
dsExcel = new DataSet();
try
{
da.Fill(dsExcel);
}
catch (Exception ex)
{
writeErrorToFile(ex.Message + " -- (t_Elapsed -> Keep valid excel file which you want to upload..) --");
//lblMsg.Text = "Keep valid excel file which you want to upload..";
return;
}
//lblMsg.Text = "Data retrieved successfully! Total Records:" + dsExcel.Tables[0].Rows.Count;
da.Dispose();
conn.Close();
conn.Dispose();
if (dsExcel.Tables[0].Columns.Count != 32)
{
writeErrorToFile("Please check the Excel Sheet.. It contains more or less columns..");
return;
}
if (dsExcel.Tables[0].Rows.Count > 0)
{
for (int i = 0; i < dsExcel.Tables[0].Rows.Count; i++)
File.AppendAllText(#"C:\E-Cata_Itms.txt", dsExcel.Tables[0].Rows[i][0].ToString() + " \n\r"+i+i);
}
//======================================================================================================
string con = getConn_string();
SqlConnection sn = new SqlConnection(con);
if (sn.State == ConnectionState.Open)
sn.Close();
sn.Open();
SqlTransaction transaction = sn.BeginTransaction();
try
{
for (int j = 4; j < dsExcel.Tables[0].Rows.Count; j++) // for rows
{
for (int i = 2; i < 32; i++) //for coloumns
{
sm = new SqlCommand();
sm.Transaction = transaction;
sm.CommandText = "whItmItemwise_upload_update";
sm.Connection = sn;
sm.CommandType = CommandType.StoredProcedure;
sm.Parameters.AddWithValue("#whItm_wh_code", dsExcel.Tables[0].Rows[3][i].ToString().Trim());
sm.Parameters.AddWithValue("#whItm_item_code", dsExcel.Tables[0].Rows[j][0].ToString().Trim());
try
{
// open stock quantity
decimal op_qty = (dsExcel.Tables[0].Rows[j][i].ToString().Trim() ==
"")
? Convert.ToDecimal(0.0)
: Convert.ToDecimal(
dsExcel.Tables[0].Rows[j][i].ToString().Trim
());
sm.Parameters.AddWithValue("#whItm_OP_STK_Qty", op_qty);
}
catch (Exception ex)
{
writeErrorToFile(ex.Message + " -- (t_Elapsed -> Enter valid Open stock quantity..) --"+i);
return;
}
sm.Parameters.AddWithValue("#whItm_Creation_DT", DateTime.Now.ToString("yyyy/MM/dd"));
//sm.Parameters.AddWithValue("#whItm_Created_By", "");
//sm.Parameters.AddWithValue("#His_whItm_Modify_Del_DT", DateTime.Now.ToString("yyyy/MM/dd"));
//sm.Parameters.AddWithValue("#His_whItm_Modify_Del_By", "");
try
{
int x = sm.ExecuteNonQuery();
}
catch (Exception ex)
{
System.Text.StringBuilder str_Upload = new System.Text.StringBuilder();
str_Upload.Append(dsExcel.Tables[0].Rows[3][i].ToString().Trim() + ",");
str_Upload.Append(dsExcel.Tables[0].Rows[j][0].ToString().Trim() + ",");
str_Upload.Append(ex.Message.Replace(',', '-') + ",");
str_Upload.Append(DateTime.Now.ToString("dd/MM/yyyy") + ",");
File.AppendAllText(#"C:\E-Cata_Error" + ".csv", str_Upload.ToString());
}
sm.Parameters.Clear();
}
}
// Update stock from WH master to Item Master
SqlCommand sm2 = new SqlCommand();
sm2.Transaction = transaction;
sm2.CommandText = "Stock_Update_from_WH_to_Item_master";
sm2.Connection = sn;
sm2.CommandType = CommandType.StoredProcedure;
sm2.Parameters.AddWithValue("#Item_Code", "");
sm2.ExecuteNonQuery();
transaction.Commit();
sm2.Dispose();
MyNewService iyu = new MyNewService();
iyu.Stop();
}
catch (Exception ex)
{
transaction.Rollback();
writeErrorToFile(ex.Message+"abcd");
return;
}
finally
{
sm.Dispose();
transaction.Dispose();
sn.Close();
sn.Dispose();
}
//try
//{
// // delete uploaded file
// File.Delete(strNewPath);
//}
//catch (Exception)
//{
//}
}
catch (Exception ex)
{
writeErrorToFile(ex.Message + " -- (t_Elapsed) --"+"xyz");
}
}
Windows service has to inherit from ServiceBase class. It has OnStart and OnStop virtual methods that we need to override in the service class.
In your code, when the windows service is started, OnStart method is invoked. In this method the timer is enabled and set the interval to 10 sec. Timer interval always sets in milliseconds, that’s why value is 10000. When 10 sec elapsed the method subscribed in the Elapsed event is fired, in this case the t_Elapsed method in fired.
See the following article for hosting the wcf service in a managed windows service.
http://msdn.microsoft.com/en-us/library/ms733069.aspx
Related
I'm new here but I need some help. I need to update a SQL Server database from C# with Windows Forms, but I'm having problems. I looked it up but still can't find the right answer. I need to do insert and update by pressing a button for changing or filling the database from the datagridview. I've created a separate function for both I am using this code;
private void InsertPositionen()
{
string qry = "";
SqlCommand insert = new SqlCommand(qry, con);
try
{
for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
{
qry = "INSERT INTO BelegePositionen (BelID, BelPosId, Artikelnummer, Menge, Preis) VALUES( " + dataGridView1.Rows[i].Cells["BelID"] + ", "
+ dataGridView1.Rows[i].Cells["BelPosId"] + ", "
+ dataGridView1.Rows[i].Cells["Artikelnummer"] + ", "
+ dataGridView1.Rows[i].Cells["Menge"] + ", "
+ dataGridView1.Rows[i].Cells["Preis"];
}
insert.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void UpdatePositionen()
{
string updt = "";
SqlCommand update = new SqlCommand(updt, con);
try
{
for (int i = 0; i < dataGridView1.Rows.Count -1; i++)
{
updt = "UPDATE BelegePositionen SET BelID = "
+ dataGridView1.Rows[i].Cells["BelID"] +
", BelPosID = "
+ dataGridView1.Rows[i].Cells["BelPosID"] +
", Atrikelnummer = "
+ dataGridView1.Rows[i].Cells["Artikelnummer"] +
", Menge = "
+ dataGridView1.Rows[i].Cells["Menge"] +
", Preis = "
+ dataGridView1.Rows[i].Cells["Preis"];
}
update.ExecuteNonQuery();
con.Close();
MessageBox.Show("Done!");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
You should really NOT do your SQL stuff like this!! This leaves your code wide open for SQL injection vulnerabilities! Stop that - right now!
Instead - use parametrized queries - like this:
private void InsertPositionen()
{
string qry = "INSERT INTO BelegePositionen (BelID, BelPosId, Artikelnummer, Menge, Preis) " +
"VALUES(#BelId, #BelPosId, #ArtNr, #Menge, #Preis);";
SqlCommand insert = new SqlCommand(qry, con);
// define the parameters
insert.Parameters.Add("#BelId", SqlDbType.Int);
insert.Parameters.Add("#BelPosId", SqlDbType.Int);
insert.Parameters.Add("#ArtNr", SqlDbType.Int); // maybe this is a string?
insert.Parameters.Add("#Menge", SqlDbType.Int);
insert.Parameters.Add("#Preis", SqlDbType.Decimal, 20, 4);
try
{
// in the loop, only *set* the parameter's values
for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
{
insert.Parameters["#BelId"].Value = 1;
insert.Parameters["#BelPosId"].Value = 2;
insert.Parameters["#ArtNr"].Value = 3;
insert.Parameters["#Menge"].Value = 4;
insert.Parameters["#Preis"].Value = 99.95;
insert.ExecuteNonQuery();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Your Question is quite vague as you state you are having problems, but not quite sure what problems you are having. It will help if you can describe what problems you are having.
In addition to what #marc_c said about sql injection, I can't see how you manage your connection to the database.
From the code it looks like you could run into a situation where you are leaving connection strings open, or not opening them at all.
using the using(...) { } will close the connections when you are done with it.
private void InsertPositionen()
{
//using the using statement you will insure that the connection is closed and resources released
using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.db))
{
string cmd = "INSERT INTO BelegePositionen (BelID, BelPosId, Artikelnummer, Menge, Preis) " +
"VALUES(#BelId, #BelPosId, #ArtNr, #Menge, #Preis);";
//using the using statement will ensure any reasources are released when exiting the code block
using (SqlCommand insert = new SqlCommand(cmd, connection))
{
// define the parameters
insert.Parameters.Add("#BelId", SqlDbType.Int);
insert.Parameters.Add("#BelPosId", SqlDbType.Int);
insert.Parameters.Add("#ArtNr", SqlDbType.Int); // maybe this is a string?
insert.Parameters.Add("#Menge", SqlDbType.Int);
insert.Parameters.Add("#Preis", SqlDbType.Decimal, 20, "4");
try
{
//open the connection
insert.Connection.Open();
// in the loop, only *set* the parameter's values
for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
{
insert.Parameters["#BelId"].Value = dataGridView1.Rows[i].Cells["BelID"];
insert.Parameters["#BelPosId"].Value = dataGridView1.Rows[i].Cells["BelPosId"];
insert.Parameters["#ArtNr"].Value = dataGridView1.Rows[i].Cells["Artikelnummer"];
insert.Parameters["#Menge"].Value = dataGridView1.Rows[i].Cells["Menge"];
insert.Parameters["#Preis"].Value = dataGridView1.Rows[i].Cells["Preis"];
insert.ExecuteNonQuery();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
MessageBox.Show("Done!");
}
}
}
}
I'm working on an app with an Access 2010 db connection and I keep receiving OleDB error 80004005 and I can't figure out why.
const String conn = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:\OneDrive\Dropbox\SharpDevelop Projects\electronics inventory\electronics.mdb";
const String qCont = "select Section, Number, Stock from Container where Component = #IdComp order by Section, Number";
int oldParamSubcat = 0;
OleDbConnection connection = new OleDbConnection(conn);
void GrdCompCellClick(object sender, DataGridViewCellEventArgs e)
{
String IdComp = grdComp[grdComp.Columns["ID"].Index, grdComp.CurrentCell.RowIndex].Value.ToString();
try
{
grdSubcat.DataSource = null;
grdSubcat.Rows.Clear();
grdSubcat.Columns.Clear();
connection.Open();
OleDbCommand cmdDetail = new OleDbCommand();
cmdDetail.Connection = connection;
cmdDetail.CommandText = qDetail;
cmdDetail.Parameters.AddWithValue("#IdComp", Convert.ToInt32(IdComp));
txtDetails.Text = "";
OleDbDataReader rdDetail = cmdDetail.ExecuteReader();
rdDetail.Read();
txtDetails.Text = rdDetail["Component"].ToString() + "\r\n";
txtDetails.Text += rdDetail["Parameter"].ToString() + ": ";
txtDetails.Text += rdDetail["Val"].ToString() + "\r\n";
while(rdDetail.Read())
{
txtDetails.Text += rdDetail["Parameter"].ToString() + ": ";
txtDetails.Text += rdDetail["Val"].ToString() + "\r\n";
}
rdDetail.Close();
connection.Close();
connection.Open();
OleDbCommand cmdCode = new OleDbCommand();
cmdCode.Connection = connection;
cmdCode.CommandText = qCode;
cmdCode.Parameters.AddWithValue("#IdComp", Convert.ToInt32(IdComp));
txtDetails.Text += "\r\n";
OleDbDataReader rdCode = cmdCode.ExecuteReader();
while(rdCode.Read())
{
txtDetails.Text += rdCode["Seller"].ToString() + ": ";
txtDetails.Text += rdCode["Code"].ToString() + "\r\n";
}
rdCode.Close();
connection.Close();
connection.Open();
OleDbCommand cmdCont = new OleDbCommand();
cmdCont.Connection = connection;
cmdCont.CommandText = qCont;
cmdCont.Parameters.AddWithValue("#IdComp", Convert.ToInt32(IdComp));
txtDetails.Text += "\r\n";
OleDbDataReader rdCont = cmdCont.ExecuteReader(); ////////// here is where i receive the error ///////////////
while(rdCont.Read())
{
txtDetails.Text += "Container: ";
txtDetails.Text += rdCont["Section"].ToString() + "-";
txtDetails.Text += rdCont["Number"].ToString() + " = ";
txtDetails.Text += rdCont["Stock"].ToString() + " units\r\n";
}
rdCont.Close();
connection.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
The rest of the code works perfectly, I only get the error on cmdCont.ExecuteReader();
The error message
If i execute the query in Access, it runs ok.
Any ideas are very much welcome.
Thanks.
The words Section, Number and Container are listed between the reserved keyword for MS-Access. You shouldn't use them in your table schema but if you really can't change these names to something different then you need to put them between square brackets
const String qCont = #"select [Section], [Number], Stock from [Container]
where Component = #IdComp order by [Section], [Number]";
Also you should use a more robust approach to your disposable objects like the connection, the commands and the readers. Try to add the using statement to your code in this way:
try
{
....
using(OleDbConnection connection = new OleDbConnection(......))
{
connection.Open();
....
string cmdText = "yourdetailquery";
using(OleDbCommand cmdDetail = new OleDbCommand(cmdText, connection))
{
.... // parameters
using(OleDbDataReader rdDetail = cmdDetail.ExecuteReader())
{
... read detail data ....
}
}
// here the rdDetail is closed and disposed,
// you can start a new reader without closing the connection
cmdText = "yourcodequery";
using(OleDbCommand cmdCode = new OleDbCommand(cmdText, connection))
{
.... parameters
using(OleDbReader rdCode = cmdCode.ExecuteReader())
{
// read code data...
}
}
... other command+reader
}
// Here the connection is closed and disposed
}
catch(Exception ex)
{
// any error goes here with the connection closed
}
I am executing UPDATE OR INSERT command with WHERE statement and I've got this error:
Here is my code:
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
try
{
FbConnection con = new FbConnection(#"User = SYSDBA; Password = masterkey; Database = D:\TDWORK.fdb; DataSource = localhost; Port = 3050; Dialect = 3; Charset = NONE; Role = admin; Connection lifetime = 15; Pooling = true; MinPoolSize = 0; MaxPoolSize = 50; Packet Size = 8192; ServerType = 0; ");
FbCommand cmd = new FbCommand("UPDATE OR INSERT INTO ZAPOSLENI (ULOGA) VALUES (" + dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString() + ") WHERE ZAPID = " + dataGridView1.Rows[e.RowIndex].Cells[0].Value + " ", con);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
And here is how command looks like when debugger insert values in it:
UPDATE OR INSERT INTO ZAPOSLENI (ULOGA) VALUES (1) WHERE ZAPID = 0
You cannot use WHERE in an insert or update clause (see UPDATE OR INSERT). If you want to insert a row, when there is no record with ZAPID = 0 use the following statement:
UPDATE OR INSERT INTO ZAPOSLENI (ZAPID, ULOGA) VALUES (0, 1) MATCHING (ZAPID)
EDIT: Complete example
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
try
{
FbConnection con = new FbConnection(#"User = SYSDBA; Password = masterkey; Database = D:\TDWORK.fdb; DataSource = localhost; Port = 3050; Dialect = 3; Charset = NONE; Role = admin; Connection lifetime = 15; Pooling = true; MinPoolSize = 0; MaxPoolSize = 50; Packet Size = 8192; ServerType = 0; ");
FbCommand cmd = new FbCommand("UPDATE OR INSERT INTO ZAPOSLENI (ZAPID, ULOGA) VALUES (" + dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString() + ", " + dataGridView1.Rows[e.RowIndex].Cells[0].Value + ") MATCHING (ZAPID)", con);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
I was looking through dozens of articles, but couldn't find a solution.
Here is the logic :
I have a Winform (VS2010) application, that needs to read data from SQL Server 2008 R2 Express table A, process some calculations and store in a different table B.
I want to use parallel ForEach in order to shorten execution time (otherwise the calculation + SQL process takes days.....)
I have to read from SQL, because the database has over 5 million rows, each read returns a few hundreds rows.
Lists are defined as :
BindingList<ItemsClass> etqM = new BindingList<ItemsClass>();
BindingList<ItemsClass> etqC = new BindingList<ItemsClass>();
The parallel execution :
Parallel.ForEach(etqC, cv => {
readData(ref etqM, "tableA", "WHERE ID LIKE '" + cv.Name + "%'");
IList<ItemsClass> eResults = etqM.OrderBy(f => f.ID).ToList();
foreach (ItemsClass R in eResults)
{
//calculations comes here
etqM[rID] = R;
}
Parallel.ForEach(etqM, r => {
// part 2 of calculations comes here
}
});
exportList(etqM, "tableB", true);
});
The SQL Read function :
The function gets a List, Table name + conditions for the SQL
read from SQL the records, and transform them to the List format.
public void readData<T>(ref BindingList<T> etqList, string tableName, string conditions)
{
SqlConnection myConnection = new SqlConnection();
SqlCommand myCommand = new SqlCommand();
myCommand.CommandTimeout = 0;
myCommand.Connection = myConnection;
etqList.Clear();
openConn(myConnection);
SqlDataReader myReader = null;
try
{
int totalResults;
myCommand.CommandText = "SELECT COUNT (*) FROM " + tableName + " " + conditions;
totalResults = (int)myCommand.ExecuteScalar();
if (totalResults > 0)
{
myCommand.CommandText = "SELECT * FROM " + tableName + " " + conditions;
myReader = myCommand.ExecuteReader();
etqList = ConvertTo<T>(convertReaderToDT(myReader));
}
}
catch (Exception ex) { }
finally
{
try { myReader.Close(); }
catch { }
}
closeConn(myConnection);
}
The SQL export function : this function exports the given list to the table name.
private void exportListToSql<T>(IEnumerable<T> etqList, string tableName)
{
SqlConnection myConnection = new SqlConnection();
SqlCommand myCommand = new SqlCommand();
myCommand.CommandTimeout = 0;
myCommand.Connection = myConnection;
openConn(myConnection);
try
{
actionTotalCount++;
DataTable dt = new DataTable(tableName);
dt = ToDataTable(etqList);//List Name
var bulkCopy = new SqlBulkCopy(myConnection,
SqlBulkCopyOptions.TableLock |
SqlBulkCopyOptions.FireTriggers |
SqlBulkCopyOptions.UseInternalTransaction,
null
);
bulkCopy.DestinationTableName = tableName;
bulkCopy.BatchSize = BATCH_SIZE;
bulkCopy.WriteToServer(dt);
}
catch (Exception ex) { }
finally { closeConn(myConnection); }
}
SQL openConn and closeConn :
void openConn(SqlConnection myConnection)
{
if (myConnection.State == ConnectionState.Open) return;
myConnection.ConnectionString = "Data Source=" + DB_NAME + ";Initial Catalog=APPDB;Integrated Security=True;Connect Timeout=120;Asynchronous Processing=true;";
try { myConnection.Open(); actionTotalCount++; }
catch (System.Exception ex) { MessageBox.Show(ex.Message); }
}
void closeConn(SqlConnection myConnection)
{
if (myConnection.State == ConnectionState.Fetching || myConnection.State == ConnectionState.Executing || myConnection.State == ConnectionState.Connecting) return;
try { myConnection.Dispose(); }
catch (System.Exception ex) { MessageBox.Show(ex.Message); }
}
The problem is : once I execute, I get this message :
ExecuteScalar requires an open and available connection. The connection's current state is closed.
This message arrives for all threads, except the first one.
Any ideas ?
Apparently the problem was not in the SQL, but the calculations.
Since the List was defined outside the 'Parallel.Foreach', it was accesses by different threads simultaneously, causing a crash.
Once I changed the code as followed, all worked excellent :
Parallel.ForEach(etqC, cv => {
BindingList<ItemsClass> etqM = new BindingList<ItemsClass>();
readData(ref etqM, "tableA", "WHERE ID LIKE '" + cv.Name + "%'");
IList<ItemsClass> eResults = etqM.OrderBy(f => f.ID).ToList();
foreach (ItemsClass R in eResults)
{
//calculations comes here
etqM[rID] = R;
}
Parallel.ForEach(etqM, r => {
// part 2 of calculations comes here
}
});
exportList(etqM, "tableB", true);
});
Hi all i have written the following transaction to insert data but when i am getting an exception only the data which got the exception not inserting to db the remaining all are inserting
This is what i wrote
public bool addWhole(SqlTransaction osqlTrans)
{
m_flag = false;
osqlTrans = null;
SqlConnection osqlCon = new SqlConnection(constr);
if (osqlCon.State != ConnectionState.Open)
{
osqlCon.Open();
}
osqlTrans = osqlCon.BeginTransaction();
try
{
if (this.addRisk(osqlTrans, osqlCon))
{
if (this.addEconomical(osqlTrans, osqlCon))
{
osqlTrans.Commit();
}
}
}
catch (Exception ex)
{
osqlTrans.Rollback();
}
finally
{
osqlCon.Close();
}
return m_flag;
}
public bool addRisk(SqlTransaction oRiskTrans, SqlConnection oRiskConn)
{
con = new SqlConnection(constr);
if (con.State != ConnectionState.Open)
{
con.Open();
}
cmd = new SqlCommand("insert into tblEnrollmentData (EID,Eyear,Epercent) values('" + id + "','" + str + "','" + dbPercent + "')", con); //Even i tried adding transaction in command statement
if (cmd.ExecuteNonQuery() > 0)
{
m_flag = true;
}
}
public bool addEconomical(SqlTransaction oRiskTrans, SqlConnection oRiskConn)
{
con = new SqlConnection(constr);
if (con.State != ConnectionState.Open)
{
con.Open();
}
cmd = new SqlCommand("insert into tblEnrollmentData (EID,Eyear,Epercent) values('" + id + "','" + str + "','" + dbPercent + "')", con);//Even i tried adding transaction in command statement
if (cmd.ExecuteNonQuery() > 0)
{
m_flag = true;
}
}
I tried to rollback the transaction by failing the second condition but my first statement is inserting to DB.. What should i do in order to overcome this
I'm guessing its one of these things
1) You are not using the same connection object for all the different commands
2) You are not assigning the transaction to the commands before you execute them
3) Both perhaps
Try using the same connection object and assigning the transaction to the command before you execute it for an example see this page on MSDN. http://msdn.microsoft.com/en-us/library/86773566.aspx
Transaction is not shared between connections and you always create a new connection. Use oRiskConn specified as 2nd parameter of your methods.
As you are creating a new connection in every function your code didn't work. Just remove the connection
`con = new SqlConnection(constr);`
Replace it with the connection available in your function i.e
oRiskConn and don't initialize it as a new connection. If you did so again your transaction as per your requirement will not work. Also include oRiskTrans in your command object. Then it will works as per your requirement
I don't know what some of your parameters are but it looks like you want something like this:
class SomeClass
{
// These need to be set to appropriate values
int id, str;
double dbPercent;
string constr;
public bool addWhole()
{
var m_flag = false;
using (var osqlCon = new SqlConnection(constr))
{
if (osqlCon.State != ConnectionState.Open)
{
osqlCon.Open();
}
using (var osqlTrans = osqlCon.BeginTransaction())
{
try
{
if (m_flag = this.addRisk(osqlTrans))
{
if (m_flag = this.addEconomical(osqlTrans))
{
osqlTrans.Commit();
}
}
}
catch (Exception)
{
// Use $exception in watch window if you are debugging
osqlTrans.Rollback();
}
}
}
return m_flag;
}
public bool addRisk(SqlTransaction oRiskTrans)
{
var m_flag = false;
using (var cmd = new SqlCommand("insert into tblEnrollmentData (EID,Eyear,Epercent) values('" + id + "','" + str + "','" + dbPercent + "')"))
{
cmd.Transaction = oRiskTrans;
cmd.Connection = oRiskTrans.Connection;
if (cmd.ExecuteNonQuery() > 0)
{
m_flag = true;
}
}
return m_flag;
}
public bool addEconomical(SqlTransaction oRiskTrans)
{
var m_flag = false;
using (var cmd = new SqlCommand("insert into tblEnrollmentData (EID,Eyear,Epercent) values('" + id + "','" + str + "','" + dbPercent + "')"))
{
cmd.Transaction = oRiskTrans;
cmd.Connection = oRiskTrans.Connection;
if (cmd.ExecuteNonQuery() > 0)
{
m_flag = true;
}
}
return m_flag;
}
}