I'm selecting about 20,000 records from the database and then I update them one by one.
I looked for this error and I saw that setting the CommandTimeout will help, but not in my case.
public void Initialize()
{
MySqlConnectionStringBuilder SQLConnect = new MySqlConnectionStringBuilder();
SQLConnect.Server = SQLServer;
SQLConnect.UserID = SQLUser;
SQLConnect.Password = SQLPassword;
SQLConnect.Database = SQLDatabase;
SQLConnect.Port = SQLPort;
SQLConnection = new MySqlConnection(SQLConnect.ToString());
}
public MySqlDataReader SQL_Query(string query)
{
MySqlCommand sql_command;
sql_command = SQLConnection.CreateCommand();
sql_command.CommandTimeout = int.MaxValue;
sql_command.CommandText = query;
MySqlDataReader query_result = sql_command.ExecuteReader();
return query_result;
}
public void SQL_NonQuery(string query)
{
MySqlCommand sql_command;
sql_command = SQLConnection.CreateCommand();
sql_command.CommandTimeout = int.MaxValue;
sql_command.CommandText = query;
sql_command.ExecuteNonQuery();
}
And here is my method which makes the select query:
public void CleanRecords()
{
SQLActions.Initialize();
SQLActions.SQL_Open();
MySqlDataReader cashData = SQLActions.SQL_Query("SELECT `cash`.`id`, SUM(`cash`.`income_money`) AS `income_money`, `cash_data`.`total` FROM `cash_data` JOIN `cash` ON `cash`.`cash_data_id` = `cash_data`.`id` WHERE `user`='0' AND `cash_data`.`paymentterm_id`='0' OR `cash_data`.`paymentterm_id`='1' GROUP BY `cash_data_id`");
while(cashData.Read()){
if(cashData["income_money"].ToString() == cashData["total"].ToString()){
UpdateRecords(cashData["id"].ToString());
}
}
SQLActions.SQL_Close();
}
And here is the method which makes the update:
public void UpdateRecords(string rowID)
{
SQLActions.Initialize();
SQLActions.SQL_Open();
SQLActions.SQL_NonQuery("UPDATE `cash_data` SET `end_date`='" + GetMeDate() + "', `user`='1' WHERE `id`='" + rowID + "'");
SQLActions.SQL_Close();
}
Changing the database structure is not an option for me.
I thought that setting the timeout to the maxvalue of int will solve my problem, but is looks like this wont work in my case.
Any ideas? :)
EDIT:
The error which I get is "Fatal error encoutered during data read".
UPDATE:
public void CleanRecords()
{
StringBuilder dataForUpdate = new StringBuilder();
string delimiter = "";
SQLActions.Initialize();
SQLActions.SQL_Open();
MySqlDataReader cashData = SQLActions.SQL_Query("SELECT `cash`.`id`, SUM(`cash`.`income_money`) AS `income_money`, `cash_data`.`total` FROM `cash_data` JOIN `cash` ON `cash`.`cash_data_id` = `cash_data`.`id` WHERE `user`='0' AND `cash_data`.`paymentterm_id`='0' OR `cash_data`.`paymentterm_id`='1' GROUP BY `cash_data_id`");
while (cashData.Read())
{
if (cashData["income_money"].ToString() == cashData["total"].ToString())
{
dataForUpdate.Append(delimiter);
dataForUpdate.Append("'" + cashData["id"].ToString() + "'");
delimiter = ",";
}
}
SQLActions.SQL_Close();
UpdateRecords(dataForUpdate.ToString());
}
public void UpdateRecords(string rowID)
{
SQLActions.Initialize();
SQLActions.SQL_Open();
SQLActions.SQL_NonQuery("UPDATE `cash_data` SET `end_date`='" + GetMeDate() + "', `user`='1' WHERE `id` IN (" + rowID + ")");
SQLActions.SQL_Close();
}
You may be able to use
UPDATE cash_data .... WHERE id IN (SELECT ....)
and do everything in one go. Otherwise, you could do it in two steps: first the select collects all the ids, close the connection and then do the update in obne go with all the ids.
The code for the second option might look something like this:
public void CleanRecords()
{
StringBuilder builder = new StringBuilder();
string delimiter = "";
SQLActions.Initialize();
SQLActions.SQL_Open();
MySqlDataReader cashData = SQLActions.SQL_Query("SELECT `cash`.`id`, SUM(`cash`.`income_money`) AS `income_money`, `cash_data`.`total` FROM `cash_data` JOIN `cash` ON `cash`.`cash_data_id` = `cash_data`.`id` WHERE `user`='0' AND `cash_data`.`paymentterm_id`='0' OR `cash_data`.`paymentterm_id`='1' GROUP BY `cash_data_id`");
while(cashData.Read()){
if(cashData["income_money"].ToString() == cashData["total"].ToString()){
builder.Append(delimiter);
builder.Append("'" + cashData["id"].ToString() + "'");
delimiter = ",";
}
}
SQLActions.SQL_Close();
UpdateRecords(builder.ToString());
}
public void UpdateRecords(string rowIDs)
{
SQLActions.Initialize();
SQLActions.SQL_Open();
SQLActions.SQL_NonQuery("UPDATE `cash_data` SET `end_date`='" + GetMeDate() + "', `user`='1' WHERE `id` IN (" + rowIDs + ")";
SQLActions.SQL_Close();
}
There are multiple problem:
First: You have reading information around 20K using data reader and then doing update one by one in reader itself. Reader holds the connection open until you are finished. So this is not the good way to do it. Solution: We can read the information using Data Adapter.
Second: Rather than doing one by one update, we can update in bulk in one go. There are multiple option for bulk operation. In SQL u can do either by sending information in XML format or u can use Table Valued Parameter (TVP) (http://www.codeproject.com/Articles/22205/ADO-NET-and-OPENXML-to-Perform-Bulk-Database-Opera) OR (http://dev.mysql.com/doc/refman/5.5/en/load-xml.html)
Related
Good day,
In c#, I am trying to run a MySQL update query to update one record, based on its id. Everything goes well as long as I'm not using parameters.
I'm experiencing the issue once I am adding one or several parameters. I have made the test with only one parameter and same problem here.
What am I missing here ?
Thank you very much for your help.
public static void editCustomerTest(ClsCustomerTest pTest)
{
MySqlConnection l_Connection = null;
string l_SpName = string.Empty;
MySqlCommand l_MyCommand = null;
try
{
l_Connection = ClsIconEnv.getDataAccess().MySqlConnection;
ClsDataAccess.OpenConnection(l_Connection);
l_SpName = "update tbTestCustomers " +
"set sName = '#sLastName', " +
"sFirstName = '#sFirstName', " +
"sAddress = '#sAddress' " +
"Where id = #id);";
l_MyCommand = new MySqlCommand(l_SpName, l_Connection);
l_MyCommand.Parameters.Add("#sLastName", pTest.Last_Name);
l_MyCommand.Parameters.Add("#sFirstName", pTest.First_name);
l_MyCommand.Parameters.Add("#sAddress", pTest.Address);
l_MyCommand.Parameters.Add("#id", pTest.id);
l_MyCommand.ExecuteNonQuery(); // <----- This is the line at which the execution stops
ClsDataAccess.CloseConnection(l_Connection);
}
catch (Exception exc)
{
ClsIconErrorManager.manageException(exc);
}
finally
{
}
}
You do not need to wrap your params into the string and you have to use AddWithValue instead of Add if you don't want to explicitly specify the type, like this
l_SpName = "update tbTestCustomers " +
"set sName = #sLastName, " +
"sFirstName = #sFirstName, " +
"sAddress = #sAddress" +
"Where id = #id);";
l_MyCommand.Parameters.AddWithValue("#sLastName", pTest.Last_Name);
l_MyCommand.Parameters.AddWithValue("#sFirstName", pTest.First_name);
l_MyCommand.Parameters.AddWithValue("#sAddress", pTest.Address);
l_MyCommand.Parameters.AddWithValue("#id", pTest.id);
Like this:
l_SpName = #"update tbTestCustomers
set sName = #sLastName,
sFirstName = #sFirstName,
sAddress = #sAddress
Where id = #id";
l_MyCommand = new MySqlCommand(l_SpName, l_Connection);
l_MyCommand.Parameters.AddWithValue("#sLastName", pTest.Last_Name);
l_MyCommand.Parameters.AddWithValue("#sFirstName", pTest.First_name);
l_MyCommand.Parameters.AddWithValue("#sAddress", pTest.Address);
l_MyCommand.Parameters.AddWithValue("#id", pTest.id);
l_MyCommand.ExecuteNonQuery();
I am trying to write a method which is supposed to retrieve multiple rows from a table in a database and use those data to instantiate a number of objects. However, as far as i can tell the database only returns the first row. When i do this:
public static List<Event> getMultipleEvents(string[] eventNames)
{
List<Event> rtnList = new List<Event>();
string EventsToRetrieve = "";
foreach (var item in eventNames)
{
if (EventsToRetrieve != "")
{
EventsToRetrieve += " OR ";
}
EventsToRetrieve += "eventName = '";
EventsToRetrieve += item;
EventsToRetrieve += "' ";
}
// This is the string that the method constructs based on the input i am testing with
//"eventName = 'event six' OR eventName = ' event two' OR eventName = ' event one' OR eventName = ' event seven' "
using (SqlConnection sqlConnection = Globals.GetSqlConnection())
{
sqlConnection.Open();
using (SqlCommand sqlCommand = new SqlCommand("SELECT * FROM questions WHERE " + EventsToRetrieve + ";", sqlConnection))
{
using (SqlDataReader sqlDataReader = sqlCommand.ExecuteReader())
{
if (sqlDataReader != null)
{
while (sqlDataReader.Read())
{
Event newEvent = new Event("", DateTime.MinValue, DateTime.MinValue);
string startDateTimeStringFromDB = sqlDataReader["startDateDay"].ToString() + "-" + sqlDataReader["startDateMonth"].ToString() + "-" + sqlDataReader["startDateYear"].ToString();
string endDateTimeStringFromDB = sqlDataReader["endDateDay"].ToString() + "-" + sqlDataReader["endDateMonth"].ToString() + "-" + sqlDataReader["endDateYear"].ToString();
newEvent.EventName = sqlDataReader["eventName"].ToString();
if (DateTime.TryParse(startDateTimeStringFromDB, out DateTime startDateTime))
{
newEvent.StartDate = startDateTime;
}
if (DateTime.TryParse(endDateTimeStringFromDB, out DateTime endDateTime))
{
newEvent.EndDate = endDateTime;
}
rtnList.Add(newEvent);
}
}
}
}
}
return rtnList;
}
Can anyone explain to me what i am doing wrong ? I Also tried wrapping the while loop in a do while loop as suggested here How to read multiple resultset from SqlDataReader? but it didn't change anything.
It doesn't seem to have any error in your code. however I believe that your query has errors.
First of all never ever use string concatenation when you are building your SQL Query. Instead use Parameterized Queries.
with the parameterized queries, it is even easier to debug your SQL statement since it does not include conditional string concatenations.
I have a form with a text box and button, such that when the user clicks the button, the specified name in the text box is added to a table in my sql database. The code for the button is as follows:
private void btnAddDiaryItem_Click(object sender, EventArgs e)
{
try
{
string strNewDiaryItem = txtAddDiaryItem.Text;
if (strNewDiaryItem.Length == 0)
{
MessageBox.Show("You have not specified the name of a new Diary Item");
return;
}
string sqlText = "INSERT INTO tblDiaryTypes (DiaryType) VALUES = ('" + strNewDiaryItem + "');";
cSqlQuery cS = new cSqlQuery(sqlText, "non query");
PopulateInitialDiaryItems();
MessageBox.Show("New Diary Item added succesfully");
}
catch (Exception ex)
{
MessageBox.Show("Unhandled Error: " + ex.Message);
}
}
The class cSqlQuery is a simple class that executes various T-SQL actions for me and its code is as follows:
class cSqlQuery
{
public string cSqlStat;
public DataTable cQueryResults;
public int cScalarResult;
public cSqlQuery()
{
this.cSqlStat = "empty";
}
public cSqlQuery(string paramSqlStat, string paramMode)
{
this.cSqlStat = paramSqlStat;
string strConnection = BuildConnectionString();
SqlConnection linkToDB = new SqlConnection(strConnection);
if (paramMode == "non query")
{
linkToDB.Open();
SqlCommand sqlCom = new SqlCommand(paramSqlStat, linkToDB);
sqlCom.ExecuteNonQuery();
linkToDB.Close();
}
if (paramMode == "table")
{
using (linkToDB)
using (var adapter = new SqlDataAdapter(cSqlStat, linkToDB))
{
DataTable table = new DataTable();
adapter.Fill(table);
this.cQueryResults = table;
}
}
if (paramMode == "scalar")
{
linkToDB.Open();
SqlCommand sqlCom = new SqlCommand(paramSqlStat, linkToDB);
this.cScalarResult = (Int32)sqlCom.ExecuteScalar();
linkToDB.Close();
}
}
public cSqlQuery(SqlCommand paramSqlCom, string paramMode)
{
string strConnection = BuildConnectionString();
SqlConnection linkToDB = new SqlConnection(strConnection);
paramSqlCom.Connection = linkToDB;
if (paramMode == "table")
{
using (linkToDB)
using (var adapter = new SqlDataAdapter(paramSqlCom))
{
DataTable table = new DataTable();
adapter.Fill(table);
this.cQueryResults = table;
}
}
if (paramMode == "scalar")
{
linkToDB.Open();
paramSqlCom.Connection = linkToDB;
this.cScalarResult = (Int32)paramSqlCom.ExecuteScalar();
linkToDB.Close();
}
}
public string BuildConnectionString()
{
cConnectionString cCS = new cConnectionString();
return cCS.strConnect;
}
}
The class works well throughout my application so I don't think the error is in the class, but then I can't be sure.
When I click the button I get the following error message:
Incorrect syntax near =
Which is really annoying me, because when I run the exact same command in SQL Management Studio it works fine.
I'm sure I'm missing something rather simple, but after reading my code through many times, I'm struggling to see where I have gone wrong.
you have to remove = after values.
string sqlText = "INSERT INTO tblDiaryTypes (DiaryType) VALUES ('" + strNewDiaryItem + "');"
and try to use Parameterized queries to avoid Sql injection. use your code like this. Sql Parameters
string sqlText = "INSERT INTO tblDiaryTypes (DiaryType) VALUES (#DairyItem);"
YourCOmmandObj.Parameters.AddwithValue("#DairyItem",strNewDiaryIItem)
Remove the = after VALUES.
You do not need the =
A valid insert would look like
INSERT INTO table_name (column1, column2, column3,...)
VALUES (value1, value2, value3,...)
Source: http://www.w3schools.com/sql/sql_insert.asp
Please use following:
insert into <table name> Values (value);
Remove "=", and also i would recommend you to use string.format() instead of string concatenation.
sqlText = string.format(INSERT INTO tblDiaryTypes (DiaryType) VALUES ('{0}'), strNewDiaryItem);"
I was hoping someone could help me out with this stupid problem I'm having with the following SQL statement:
public void ApplyInference(string AnswerSelected)
{
int InferenceID;
int QuestionID;
string AnswerInference;
int PainValue;
int AnxietyValue;
int DepressionValue;
int FearValue;
int TransportValue;
int EmotionalValue;
int FinancialValue;
int PhysicalValue;
int SpiritValue;
int SocialValue;
SqlConnection NewConnection = new SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\QuestionsDatabase.mdf;Integrated Security=True;User Instance=True"); //"Initial Catalog=Northwind;Integrated Security=SSPI");
SqlDataReader ReadIn = null;
try
{
NewConnection.Open();
SqlCommand GetInference = new SqlCommand("SELECT * FROM InferenceDB WHERE QuestionID =" + this.QuestionID + "AND AnswerInference =" + AnswerSelected, NewConnection);
ReadIn = GetInference.ExecuteReader();
while (ReadIn.Read())
{
InferenceID = Convert.ToInt32(ReadIn[0]);
QuestionID = Convert.ToInt32(ReadIn[1]);
AnswerInference = Convert.ToString(ReadIn[2]);
PainValue = Convert.ToInt32(ReadIn[3]);
AnxietyValue = Convert.ToInt32(ReadIn[4]);
DepressionValue = Convert.ToInt32(ReadIn[5]);
FearValue = Convert.ToInt32(ReadIn[6]);
TransportValue = Convert.ToInt32(ReadIn[7]);
EmotionalValue = Convert.ToInt32(ReadIn[8]);
FinancialValue = Convert.ToInt32(ReadIn[9]);
PhysicalValue = Convert.ToInt32(ReadIn[10]);
SpiritValue = Convert.ToInt32(ReadIn[11]);
SocialValue = Convert.ToInt32(ReadIn[12]);
MessageBox.Show("InferenceID: " + InferenceID + "\nAnswer Value: " + AnswerInference + "\nPain value: " + PainValue + "\nSocial value: " + SocialValue);
//LoadQuestionForm(this.FormStyle);
}
}
finally
{
if (ReadIn != null)
{
ReadIn.Close();
}
if (NewConnection != null)
{
NewConnection.Close();
}
}
}`
Now the code works tor every other column in the table except for the one I need which is the AnswerInference one. I am feeding the AnswerInference value in from another method which looks like this:
private void Answer1Button_Click(object sender, EventArgs e)
{
parent.ApplyInference("Ans1");
CloseForm();
}
Unfortunately I can't get the code to work using string data found in the table I'm using. I know this should be an easy fix, but I can for the life of me work out what's going on. Can someone suggest what I'm doing wrong?
You need a space between the question-id and the and, but more importantly: you should use parameters. Look into "SQL injection", query-plan re-use, etc. The most appropriate way to do this is with a command like:
using(var GetInference = new SqlCommand(#"
SELECT *
FROM InferenceDB
WHERE QuestionID = #questionID AND AnswerInference = #answerInference"
, NewConnection);
{
GetInference.Parameters.AddWithValue("questionID", QuestionID);
GetInference.Parameters.AddWithValue("answerInference", AnswerSelected);
....
}
Also - that complex-looking try/finally can be simplified with using here.
You need a space before the AND
"SELECT *
FROM InferenceDB
WHERE QuestionID = " + this.QuestionID + " AND AnswerInference = " + AnswerSelected
I'm a VFP developer thats trying to pick up C#. Figuring that the fastest way to learn is by doing, I gave myself a small project for practice.
Objective
Move some transactions from the "live" database into an archive database.
The general idea was:
to get a list of "suitable" Jobs (parent) then to read() them one by
one.
use a foreach loop to process a list of child tables, inserting the
new record in the History database followed by deleting the old one
from the "live" table.
move the actual Job (parent) to archive, then delete it from "live"
Things went OK at the start, then I suddenly hit a brick wall....
Problem
I have a variable called RefCombo that I used to store the parent's primary key, this is stored right after the while (READ()) statement and just before the foreach loop.
In a test database of four records, the RefCombo field should have been:
while read() result: Job1
foreach childtable in my predefined list
process ChildTable1
process ChildTable2
process ChildTable3
process ChildTable4
process ChildTable5
then repeating with Job2, Job3 and Job4.
What's driving me nuts is I'm getting this instead:
while read() result: Job1
foreach childtable in my predefined list
process ChildTable1
SKIP other ChildTables, RefCombo (primary key) becomes Job2, loops back to the while read()
The thing is, once it changes to Job2, it proceeds to work exactly like I expected, looping through every single child table for each remaining parent record.
I'm also getting a "The current TransactionScope is already complete." error every other time I'm running the web page. This happens at the connection.open() part at the start of the program but it's hard to pin down since it doesn't happen all the time.
I've posted the code at the bottom, its sorta longish for a casual glance but any help would be much appreciated. I've been working on this for 2 days and really can't afford any more hair loss, lol.
Any comments on my code would also be more that welcome, I'm REALLY new to C# and every bit helps :P
Thanks in advance.
#region Declaration
DateTime FromDate = Convert.ToDateTime("01/01/2011");
DateTime ToDate = Convert.ToDateTime("01/03/2011");
string conStrSource = #"Data Source=HOME\SQLEXPRESS;Initial Catalog=MCC_Live;Integrated Security=True";
// Declare a list of child tables to check and move together with the Job
List<String> TablesToMove = new List<String>();
{
TablesToMove.Add("JobItems");
TablesToMove.Add("JobTerms");
TablesToMove.Add("JobMessages");
TablesToMove.Add("JobCalcs");
TablesToMove.Add("JobContainers");
TablesToMove.Add("JobMetrics");
}
#endregion
#region Set SQL String
string QueryString =
"SELECT " +
"JobMaster.BranchID, JobMaster.JobNo, " +
"JobMaster.ImportDate, PermitStatus.CurrentStatus " +
"FROM JobMaster. " +
"INNER JOIN PermitStatus ON " +
"JobMaster.BranchID = PermitStatus.BranchID AND " +
"JobMaster.JobNo = PermitStatus.JobNo " +
"WHERE " +
"(JobMaster.ImportDate BETWEEN #FromDate AND #ToDate) AND " +
"PermitStatus.currentStatus NOT IN ('HT0', 'HT1', 'HT2')";
#endregion
// Display on web page for reference
ASPxFromDate.Value = FromDate;
ASPxToDate.Value = ToDate;
ASPxMemo1.Value = QueryString;
#region Open Connection, Get List of filtered Master Jobs
using (SqlConnection connection = new SqlConnection(conStrSource))
{
int JobCount = 0;
ASPxListBox1.Items.Clear();
ASPxListBox2.Items.Clear();
ASPxListBox3.Items.Clear();
ASPxListBox1.Columns.Clear();
SqlCommand command = new SqlCommand(QueryString, connection);
{
command.Parameters.Add(new SqlParameter("#FromDate", FromDate));
command.Parameters.Add(new SqlParameter("#ToDate", ToDate));
}
connection.Open();
SqlDataReader FilteredJobList = command.ExecuteReader();
#endregion
try // Process MasterJob File
{
// Process individual jobs one by one so I won't tie up memory and have better logging
while (FilteredJobList.Read())
{
#region Declare variables
string RefCombo = (string)FilteredJobList[0] + (string)FilteredJobList[1]; //Get primary key
JobCount = JobCount + 1;
ASPxTextBox2.Value = JobCount;
ASPxListBox2.Items.Add(RefCombo);
#endregion
// Start transaction scope
TransactionScope TranScope = new TransactionScope();
{
try
{
// Loop through child tables
foreach (string CurrentTable in TablesToMove)
{
#region Transfer child tables
// update list so I know which part its working on
ASPxListBox1.Items.Add(CurrentTable);
RefCombo = (string)FilteredJobList[0] + (string)FilteredJobList[1];
string RefTableNow = (string)CurrentTable;
bool CancelTrans = false;
MoveChild(ref RefCombo, ref RefTableNow, ref conStrSource, ref CancelTrans);
if (CancelTrans == false)
{ //LogFailure();
break;
}
DelChild(ref RefCombo, ref RefTableNow, ref conStrSource, ref CancelTrans);
if (CancelTrans == false)
{ //LogFailure();
break;
}
#endregion
// Remove remaing entries
//MoveLatestStatus();
//DeleteLatestStatus();
//MoveMasterJob();
//DeleteMasterJob();
//LogSuccess();
TranScope.Complete();
}
catch
{
//LogFailure();
}
}
}
finally
{
FilteredJobList.Close();
}
}
}
//------------------------------------------------------------------------------------------------
private void MoveChild(ref string RefCombo, ref string CurrentTable, ref string conStrSource, ref bool CancelTrans)
{
#region Define Insert String
string InsertSqlString =
"INSERT INTO [MCC_History].[dbo].[" + #CurrentTable + "]" +
" SELECT * FROM [MCC_Live].[dbo].[" + #CurrentTable + "] s" +
" WHERE NOT EXISTS" +
" (SELECT 1 FROM [MCC_History].[dbo].[" + #CurrentTable + "] t2" +
" WHERE t2.BranchID + t2.JobNo = s.BranchID + s.JobNo)" +
" AND s.BranchID + s.JobNo = #RefCombo";
#endregion
#region Open connection and execute query
using (SqlConnection MoveConnect = new SqlConnection(conStrSource))
{
try
{
SqlCommand InsertCommand = new SqlCommand(InsertSqlString, MoveConnect);
{
InsertCommand.Parameters.Add(new SqlParameter("#RefCombo", RefCombo));
}
MoveConnect.Open();
InsertCommand.ExecuteNonQuery();
}
catch
{
CancelTrans = true;
}
}
#endregion
}
//------------------------------------------------------------------------------------------------
private void DeleteChild(ref string RefCombo, ref string CurrentTable, ref string conStrSource, ref bool CancelTrans)
{
#region Define Delete query
string DeleteSqlString =
" DELETE FROM [MCC_Live].[dbo].[" + #CurrentTable + "]" +
" WHERE [MCC_Live].[dbo].[" + #CurrentTable +
"].BranchID + [MCC_DB].[dbo].[" + #CurrentTable + "].JobNo = #RefCombo";
#endregion
#region Execute Delete query
using (SqlConnection MoveConnect = new SqlConnection(conStrSource))
{
try
{
SqlCommand InsertCommand = new SqlCommand(DeleteSqlString, MoveConnect);
{
InsertCommand.Parameters.Add(new SqlParameter("#RefCombo", RefCombo));
}
MoveConnect.Open();
InsertCommand.ExecuteNonQuery();
}
catch
{
CancelTrans = true;
}
}
#endregion
}
The problem is where you have your TranScope.Complete(); statement. It is inside of your foreach loop and it belongs after your Foreach block exits. You complete your transaction at the end of your first iteration of your list. This prevents you from making any more commands through this transaction.