I have a problem. I created a SwitchButton and want to store the state in a database table. So I created this code to debug:
SettingSwitch.CheckedChange += (s, b) =>
{
SettingDb testsetting = new SettingDb
{
Name = mItems[position].Name,
};
SettingDb test = MainActivity.db.SelectRowFromTableSettings(testsetting);
if (test != null)
{
bool SwitchValueBool = Convert.ToBoolean(test.Value);
}
bool isChecked = ValueDictionary[position];
if(isChecked == true)
{
isChecked = false;
}
else if(isChecked == false)
{
isChecked = true;
}
SettingDb setting = new SettingDb()
{
Name = SettingName.Text,
Type = "Switch",
Value = isChecked.ToString()
};
MainActivity.db.UpdateTableSettings(setting);
ValueDictionary[position] = isChecked;
SettingDb test2 = MainActivity.db.SelectRowFromTableSettings(testsetting);
if (test2 != null)
{
bool SwitchValueBool = Convert.ToBoolean(test2.Value);
}
};
The expected outcome should be:
test.Value = False
test2.Value = Opposite of test.Value, so True
But now the value I get from the table is always False. Here is the update function:
string folder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
public bool UpdateTableSettings(SettingDb setting)
{
try
{
using (var connection = new SQLiteConnection(System.IO.Path.Combine(folder, "Settings.db")))
{
connection.BeginTransaction();
connection.Query<SettingDb>("UPDATE SettingDb SET Value=? WHERE Name=?", setting.Value, setting.Name);
//connection.Update(setting);
connection.Commit();
return true;
}
}
catch (SQLiteException ex)
{
Log.Info("SQLiteEx", ex.Message);
return false;
}
}
public SettingDb SelectRowFromTableSettings(SettingDb setting)
{
try
{
using (var connection = new SQLiteConnection(System.IO.Path.Combine(folder, "Settings.db")))
{
return connection.Query<SettingDb>("SELECT * FROM SettingDb WHERE Name=?", setting.Name).FirstOrDefault();
}
}
catch (SQLiteException ex)
{
Log.Info("SQLiteEx", ex.Message);
return null;
}
}
The table value doesn't get updated!!!
Can someone tell me what I am doing wrong?
Please let me know!
According to your description, you want to update sqlite database table, please take a look the following code and modify the update function.
static void UpdateDatabase(int primaryKey, string newText, int newValue)
{
string path = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments), "mydatabase.db");
var db = new SQLiteConnection(path, false);
string sql = "UPDATE MyTable SET MyTextColumn = ?, MyValueColumn = ? WHERE MyPrimaryKey= ?";
string[] parms = new String[] { newText, newValue.ToString(), primaryKey.ToString() };
var cmd = db.CreateCommand(sql, parms);
cmd.ExecuteNonQuery();
}
I have a button click event in code behind file as follows:
protected void btnArchive_Click(object sender, EventArgs e)
{
try
{
if (projectId == 0)
{
return;
}
Int32 serverPathId = 0;
ProjectArchiveResponse archiveResponse;
if (!int.TryParse(this.ddlSourceServer.SelectedValue, out serverPathId))
return;
if (string.IsNullOrEmpty(hidFileCount.Value))
{
this.ShowMsg(this.divMessage, Resources.Resource.ProjectFileArchiveNotAllowed, MessageType.Failed);
//The project files couldn't be archived until archive operation was completed.
return;
}
ProjectManager projectManager = new ProjectManager(null, BasePage.GetCurrentUser(), null) { IsServiceCall = false};
try
{
archiveResponse = projectManager.StartProjectArchive(projectId, false, () =>
{
foreach (Control control in tdFileList.Controls.Cast<Control>())
{
if (control is Dell.AFP.UserControl.ProjectFileListBaseControl)
{
((ProjectFileListBaseControl)control).Refresh();
}
}
}, false);
if (archiveResponse.MassivePackageID > 0)
{
this.ViewState["transferPackageId"] = archiveResponse.MassivePackageID;
PopupMonitor(archiveResponse.MassivePackageID);
}
//handled for any erorrs while submitting massive package or any unhandled exceptions will be taken care here
if (archiveResponse._CustomError != null && !string.IsNullOrEmpty(archiveResponse._CustomError.Erorrmessage))
{
if (!archiveResponse._CustomError._Erorrtype.Equals(MessageType.Info))
logger.ErrorFormat("Error occurred with details : {0}", archiveResponse._CustomError.Erorrmessage);
ShowMsg(divMessage, archiveResponse._CustomError.Erorrmessage, (MessageType)archiveResponse._CustomError._Erorrtype);
}
}
catch (KnownErrorException ke)
{
//logger.Fatal("UnExpected exception occured. Exception Details " + ke.Message);
logger.Fatal(ke.Message);
if (ke.Error.Type.Equals(DELL.AFP.Management.Exceptions.ErrorType.Warning))
this.ShowMsg(this.divMessage, ke.Message, MessageType.Info);
else
this.ShowMsg(this.divMessage, ke.Message, MessageType.Failed);
}
catch (Exception ke)
{
logger.ErrorFormat("UnExpected exception has occured with details : {0} - {1}", ke.Message, ke.StackTrace);
//ShowMsg(divMessage, "UnExpected exception has occured. Details are logged. Please try after sometime", MessageType.Failed);
ShowMsg(divMessage,ke.Message, MessageType.Failed);
}
}
In this event I am calling a method StartProjectArchive which is in ProjectManager.cs file
StartProjectArchive method in ProjectManager.cs is as follows:
public ProjectArchiveResponse StartProjectArchive(int projectID, bool promoteAfterArchive, Action uiRefresh, bool waitTillTransfered, string archiveNotificationUrl = null)
{
ProjectArchiveResponse projectArchiveResponse = new ProjectArchiveResponse() { ProjectID = projectID, MassivePackageID = -1 };
string sourceServerPath = String.Empty;
int packageID =0;
Int32 sourceServerPathID = GetSourceServerPath(projectID, out sourceServerPath);
var filesWhichNeedsToBeArchived = GetFilesWhichNeedsToBeArchived(projectID, sourceServerPathID, uiRefresh);
if (objFilesNotInSourceServer != null && objFilesNotInSourceServer.Count > 0)
KnownErrorException.Throw("ePRJARCMISSFILE01", string.Join(",", objFilesNotInSourceServer.ToArray()));
if (filesWhichNeedsToBeArchived != null)
{
MassiveServiceClientProxy proxy = new MassiveServiceClientProxy();
Dictionary<string, string> files = new Dictionary<string, string>();
filesWhichNeedsToBeArchived.Select(file => new
{
SourcePath = file.FileName,
DestinationPath = Path.Combine(ConfigurationManager.AppSettings["ArchiveProcessPrefixFolder"],
Path.GetDirectoryName(file.FileName), Path.GetFileName(file.FileName),
projectFilelist.Where(pf => string.Compare(pf.FileName, file.FileName, true) == 0).First().VersionID.ToString(),
Path.GetFileName(file.FileName))
}).ToList().
ForEach(file =>
{
if (!files.ContainsKey(file.SourcePath))
files.Add(file.SourcePath, file.DestinationPath);
});
if (files.Count > 0)
{
string packageDescription = "AFP 4.0: " + projectID.ToString(),
targetServerGroupName = archiveServer.MassiveServerGroupName,
userSuppliedId = "AFP 4.0: " + EndUserInfo.UserName;
try
{
packageID = proxy.SubmitPackageWithDestinationPath(files, packageDescription, new[] { sourceServerPath },
targetServerGroupName, userSuppliedId, MassiveService.MassivePriority.URGENT, true);
}
catch (Exception ex)
{
if (IsServiceCall == true)
KnownErrorException.Throw("wPRJARCMASER01");
else
return new ProjectArchiveResponse() { _CustomError = new CustomError { _Erorrtype = Model.ErrorType.Failed, Erorrmessage = ex.Message } };
}
if (packageID > 0)
{
ProjectFileBizManager projectFileBM = new ProjectFileBizManager();
projectFileBM.InsertArchiveTransferPackageByProjectFileList(
GetProjectFileIDsByFileName(projectID, filesWhichNeedsToBeArchived.Select(file => file.FileName).ToArray()), filesWhichNeedsToBeArchived.Select(file => file.FileName).ToArray(), packageID, projectID, EndUserInfo.UserId);
TransferPackageBizManager transferPackageBM = new TransferPackageBizManager();
if (promoteAfterArchive)
{
transferPackageBM.UpdateTransferPackageFeature(packageID, promoteAfterArchive);
}
projectArchiveResponse.MassivePackageID = packageID;
if (waitTillTransfered)
{
Task<ProjectArchiveResponse> mainTask = Task<ProjectArchiveResponse>.Factory.StartNew(
() =>
{
Task<Enums.TransferStatusEnum> packageTransfer = Task<Enums.TransferStatusEnum>.Factory.StartNew(
() =>
{
try
{
TransferPackage transferPackage = null;
while (true)
{
transferPackage = transferPackageBM.GetTransferPackage(packageID);
if (transferPackage.TransferStatus.TransferStatusId == (int)Enums.TransferStatusEnum.Submitted || transferPackage.TransferStatus.TransferStatusId == (int)Enums.TransferStatusEnum.Transferring)
Thread.Sleep(8000);
else
break;
}
logger.DebugFormat("Massive package status : {0} for Package : {1}", (Enums.TransferStatusEnum)transferPackage.TransferStatus.TransferStatusId, transferPackage.TransferPackageId);
return (Enums.TransferStatusEnum)transferPackage.TransferStatus.TransferStatusId;
}
catch (Exception exp)
{
logger.ErrorFormat("Project Archive Error, while trying to find massive package status : {0}", exp);
return Enums.TransferStatusEnum.Submitted;
}
});
try
{
Int32 timeOutInMins = (ConfigurationManager.AppSettings["ProjectArchive_PackageMonitorTimeoutInMinutes"] == null) ? 60 :
Convert.ToInt32(ConfigurationManager.AppSettings["ProjectArchive_PackageMonitorTimeoutInMinutes"]);
if (!Task.WaitAll(new Task[] { packageTransfer }, timeOutInMins * 60 * 1000))
{
projectArchiveResponse.Timedout = true;
projectArchiveResponse.TransferStatus = Enums.TransferStatusEnum.Submitted;
}
else
projectArchiveResponse.TransferStatus = packageTransfer.Result;
logger.DebugFormat("Project Archive Response, Project ID: {0}\n Package ID : {1},\n IsTimedout : {2},\n Timeout value : {3} minutes, \n Transfer Status : {4}", projectArchiveResponse.ProjectID, projectArchiveResponse.MassivePackageID, projectArchiveResponse.Timedout, timeOutInMins, projectArchiveResponse.TransferStatus);
}
catch (Exception exp)
{
logger.ErrorFormat("Project Archive Error, while waiting to fetch massive package status : {0}", exp);
}
return projectArchiveResponse;
});
if (!string.IsNullOrEmpty(archiveNotificationUrl))
{
mainTask.ContinueWith((a) =>
{
try
{
AFPArchiveNotifyProxy archiveNotification = new AFPArchiveNotifyProxy();
ArchiveNotificationService.ProjectArchiveResponse archiveResponse = new ArchiveNotificationService.ProjectArchiveResponse()
{
MassivePackageID = a.Result.MassivePackageID,
ProjectID = a.Result.ProjectID,
IsTimedout = a.Result.Timedout,
ArchiveStatus = (Enum.Parse(typeof(ArchiveNotificationService.ArchiveStatusEnum), (a.Result.TransferStatus.ToString())) as ArchiveNotificationService.ArchiveStatusEnum?).Value
};
MassiveServiceClientProxy massiveServiceClientProxy = new MassiveServiceClientProxy();
FileTransferRequest[] fileTransferRequests = massiveServiceClientProxy.GetFileStatus(a.Result.MassivePackageID);
archiveResponse.Files = fileTransferRequests.Select(f => f.FileName).ToArray();
archiveNotification.ProjectArchiveUpdate(archiveNotificationUrl, archiveResponse);
logger.DebugFormat("Project Archive Response Notification, Project ID: {0}\n Package ID : {1},\n IsTimedout : {2},\n Archive Status :{3},\n Notification Url : {4},\n Total Files : {5}", archiveResponse.ProjectID, archiveResponse.MassivePackageID, archiveResponse.IsTimedout, archiveResponse.ArchiveStatus, archiveNotificationUrl, archiveResponse.Files.Count());
logger.DebugFormat("Package ID : {0}, Files : {1}", archiveResponse.MassivePackageID, string.Join(",", archiveResponse.Files.ToArray()));
}
catch (Exception exp)
{
logger.ErrorFormat("Project Archive Error, while invoking archive notification : {0}", exp);
}
});
projectArchiveResponse.TransferStatus = Enums.TransferStatusEnum.Submitted;
return projectArchiveResponse;
}
else
{
mainTask.Wait();
}
}
}
else
{
if (IsServiceCall == true)
KnownErrorException.Throw("ePRJARCMASS01");
else
return new ProjectArchiveResponse() { _CustomError = new CustomError { _Erorrtype = Model.ErrorType.Failed, Erorrmessage = "Massive has not returned the massive packageid" } };
}
}
else
{
// this.ShowMsg(this.divMessage, Resources.Resource.NoFilesToArchive, MessageType.Info);
if (IsServiceCall == true)
KnownErrorException.Throw("wPRJARCNOFILES01");
else
return new ProjectArchiveResponse() { _CustomError = new CustomError { _Erorrtype = Model.ErrorType.Info, Erorrmessage = "There are no files to archive" } };
}
}
return projectArchiveResponse;
}
In this we are taking a parameter as "Action uiRefresh" . we are calling this uiRefresh as method in GetFilesWhichNeedsToBeArchived which was in startArchiveProject method. This Refresh method in tunrn calls the method in code behind file. This was passed as a control when we are invoking startArchiveProject in code behind file. Now I have one more thing which I need to implement. I have a method Pop-Up files in code behind file. I need to call that in ProjectManager.cs class inside the Method GetFilesWhichNeedsTobeArchive. In that pop-up I will have a button and checkboxes. Upon the selection user I need to get the details from pop-up and then I have to continue with the remaining execution in ProjectManger.cs page.
Can someone help on this?
Assuming that you have a button named btnArchive then the add click event subscription, pointing to the method you have (which looks like click-event handle proc)
btnArchive.Click+=(s,e)=>btnArchive_Click(s,e);
Regards
UPDATE:
We are getting getting System.Data.SqlClient.SqlException. The message is:
Violation of PRIMARY KEY constraint 'PK_Commits'. Cannot insert duplicate key in object 'dbo.Commits'.\r\nThe statement has been terminated
It seems like EventStore is using streamid and commitid as unique id.
We use event store to append events as below.
public bool TryAppend(object[] content)
{
if (content == null)
throw new ArgumentNullException("content");
try
{
using (var stream = m_storage.OpenStream(m_streamID, 0, int.MaxValue))
{
var versionInStore = stream.StreamRevision;
content.ToList().ForEach(m =>
{
var version = ++versionInStore;
var key = string.Format("{0}-{1:00000000}", m.GetType().Name, version);
var savedMessage = new SavedRecord(key, version, m);
stream.Add(new EventMessage { Body = savedMessage });
});
stream.CommitChanges(Guid.NewGuid());
}
return true;
}
catch (Exception e)
{
m_logger.LogError(e);
return false;
}
}
The configuration of EventStore is as below. We are using Sql Serer 2008 as persistance store.
return Wireup.Init()
.LogToOutputWindow()
.UsingSqlPersistence(m_connectionName)
.WithDialect(new MsSqlDialect())
.EnlistInAmbientTransaction() // two-phase commit
.InitializeStorageEngine()
.UsingJsonSerialization()
.Compress()
.UsingSynchronousDispatchScheduler()
.DispatchTo(new DelegateMessageDispatcher(DispatchCommit))
.Build();
Any ideas why are gettin the dupplicate commit exception?
Thanks
Have got the same issue; in my case it was probably because of different threads was adding different events to the stream with same id at the same time.
Have writtent the following code to be able to retry adding events:
private void TryAddEvent(IStoreEvents storeEvents, IUserEvent anEvent, Guid streamId)
{
var isCommitSuccessful = false;
for (var i = 0; i < 10 && !isCommitSuccessful; i++)
{
try
{
using (var stream = storeEvents.OpenStream(streamId, 0, int.MaxValue))
{
stream.Add(new EventMessage {Body = anEvent});
if (stream.UncommittedEvents.All(e => e.Body != anEvent))
{
stream.Add(new EventMessage {Body = anEvent});
}
stream.CommitChanges(Guid.NewGuid());
}
isCommitSuccessful = true;
}
catch (Exception ex)
{
if (!(ex is SqlException) && !(ex is ConcurrencyException))
{
throw;
}
using (var stream = storeEvents.OpenStream(streamId, 0, int.MaxValue))
{
if (stream.CommittedEvents.Any(e => e.Body == anEvent))
{
isCommitSuccessful = true;
}
}
}
}
if (!isCommitSuccessful)
{
throw new ConcurrencyException(String.Format("Cannot add {0} to event store", anEvent.GetType()));
}
}
Hope it would help.
Q:
When I use the transactions ,I'll get the following error on about 1 out of every 100 record.
This IfxTransaction has completed; it
is no longer usable
I can't expect when the error happen or what is the reason of this error.
I try to insert about 607 record in the same transaction.
My code:
public static int InsertGroups(List<Group> groups)
{
DBConnectionForInformix con = new DBConnectionForInformix("");
con.Open_Connection();
con.Begin_Transaction();
int affectedRow = -1;
Dictionary<string, string> groupsParameter = new Dictionary<string, string>();
try
{
foreach (Group a in groups)
{
groupsParameter.Add("id", a.GroupId.ToString());
groupsParameter.Add("name", a.Name);
groupsParameter.Add("studentcount", a.StudentCount.ToString());
groupsParameter.Add("divisiontag", a.DivisionTag.ToString());
groupsParameter.Add("entireclass", a.EntireClass.ToString());
groupsParameter.Add("classid", a.ClassId.ToString());
groupsParameter.Add("depcode", a.DepCode.ToString());
groupsParameter.Add("studycode", a.StudyCode.ToString());
groupsParameter.Add("batchnum", a.BatchNum.ToString());
affectedRow = DBUtilities.InsertEntityWithTrans("groups", groupsParameter, con);
groupsParameter.Clear();
if (affectedRow < 0)
{
break;
}
}
if (affectedRow > 0)
{
con.current_trans.Commit();
}
}
catch (Exception ee)
{
string message = ee.Message;
}
con.Close_Connection();
return affectedRow;
}
public void Begin_Transaction()
{
if (this.connection.State == ConnectionState.Open)
{
this.current_trans = this.connection.BeginTransaction(IsolationLevel.Serializable);
}
}
public static int InsertEntityWithTrans(string tblName, Dictionary<string, string> dtParams, DBConnectionForInformix current_conn)
{
int Result = -1;
string[] field_names = new string[dtParams.Count];
dtParams.Keys.CopyTo(field_names, 0);
string[] field_values = new string[dtParams.Count];
string[] field_valuesParam = new string[dtParams.Count];
dtParams.Values.CopyTo(field_values, 0);
for (int i = 0; i < field_names.Length; i++)
{
field_valuesParam[i] = "?";
}
//----------------------------------------------------------------------------------------------------------------------------------------------
string insertCmd = #"INSERT INTO " + tblName + " (" + string.Join(",", field_names) + ") values (" + string.Join(",", field_valuesParam) + ")";
//----------------------------------------------------------------------------------------------------------------------------------------------
IfxCommand com = new IfxCommand(insertCmd);
for (int j = 0; j < field_names.Length; j++)
{
com.Parameters.Add("?", field_values[j]);
}
try
{
Result = current_conn.Execute_NonQueryWithTransaction(com);
if (current_conn.connectionState == ConnectionState.Open && Result > 0)//OK: logging
{
# region // Log Area
#endregion
}
}
catch (Exception ex)
{
throw;
}
return Result;
}
public int Execute_NonQueryWithTransaction(IfxCommand com)
{
string return_msg = "";
int return_val = -1;
Open_Connection();
com.Connection = this.connection;
com.Transaction = current_trans;
try
{
return_val = com.ExecuteNonQuery();
}
catch (IfxException ifxEx)// Handle IBM.data.informix : mostly catched
{
return_val = ifxEx.Errors[0].NativeError;
return_msg = return_val.ToString();
}
catch (Exception ex)// Handle all other exceptions.
{
return_msg = ex.Message;
}
finally
{
if (!string.IsNullOrEmpty(return_msg))//catch error
{
//rollback
current_trans.Rollback();
Close_Connection();
connectionstate = ConnectionState.Closed;
}
}
return return_val;
}
You seem to be handling errors and rolling back the transaction in two places (in Execute_NonQueryWithTransaction and in InsertGroups.
And the return from Execute_NonQueryWithTransaction is used both to return error codes and to return rows affected. But in InsertGroups it is checked purely as a rows affected.
Could you have an error code from Execute_NonQueryWithTransaction (so transaction rolled back) being treated as success (rows inserted) in InsertGroups and the commit then fails?
Overall the code needs significant cleanup:
A catch block to only throw is pointless and just adds noise.
Just use exceptions for error handling, all normal returns should indicate success.
My issue is the following: i'm trying to build a function to which i could pass a list of items, which would then go to the db with each of those items and update them. I believe the issue is within the way datacontexts are being used but i cannot figure out this issue.
Here is my function that builds the list of items that were changed:
protected void btnSave_Click(object sender, EventArgs e)
{
List<AFF_CMS_FMA> fmasToSave = new List<AFF_CMS_FMA>();
AFF_CMS_FMA newFmaItem = new AFF_CMS_FMA();
foreach (AFF_CMS_FMA fmaItem in FmaLib.fetchAllActiveAssetsInFMA())
{
if (fmaItem.SortOrder != Convert.ToInt32(Request.Form["fmaItem_" + fmaItem.ID + "_SortOrder"]))
{
newFmaItem = fmaItem;
newFmaItem.Name = SecurityLib.SqlSafeString(Request.Form["fmaItem_" + fmaItem.ID + "_Name"]);
newFmaItem.AssetID = Convert.ToInt32(Request.Form["fmaItem_" + fmaItem.ID + "_AssetID"]);
newFmaItem.SortOrder = Convert.ToInt32(Request.Form["fmaItem_" + fmaItem.ID + "_SortOrder"]);
newFmaItem.ImagePathEn = SecurityLib.SqlSafeString(Request.Form["fmaItem_" + fmaItem.ID + "_ImagePathEn"]);
newFmaItem.ImagePathCh = SecurityLib.SqlSafeString(Request.Form["fmaItem_" + fmaItem.ID + "_ImagePathCh"]);
newFmaItem.StartDate = DateTime.Parse(SecurityLib.SqlSafeString(Request.Form["fmaItem_" + fmaItem.ID + "_StartDate"]));
newFmaItem.EndDate = DateTime.Parse(SecurityLib.SqlSafeString(Request.Form["fmaItem_" + fmaItem.ID + "_EndDate"]));
newFmaItem.ClickToUrl = SecurityLib.SqlSafeString(Request.Form["fmaItem_" + fmaItem.ID + "_ClickToUrl"]);
fmasToSave.Add(newFmaItem);
}
}
FmaLib.saveEditedFmas(fmasToSave);
}
here is the function that the foreach loops calls to get all the items that are in the db:
public static List<AFF_CMS_FMA> fetchAllActiveAssetsInFMA()
{
List<AFF_CMS_FMA> results = null;
using (fmaDataContext db = new fmaDataContext())
{
using (TransactionScope ts = new TransactionScope())
{
try
{
if (HttpContext.Current.Cache["fmaActiveList"] == null)
{
db.LoadOptions = loadAll;
results = clsCompiledQuery.getAllActiveFmas(db).ToList();
HttpContext.Current.Cache["fmaActiveList"] = results;
}
else
results = (List<AFF_CMS_FMA>)HttpContext.Current.Cache["fmaActiveList"];
ts.Complete();
}
catch (Exception ex)
{ Transaction.Current.Rollback(); }
}
return results;
}
}
here are the queries being used:
protected static class clsCompiledQuery
{
public static Func<DataContext, IOrderedQueryable<AFF_CMS_FMA>>
getAllActiveFmas = CompiledQuery.Compile((DataContext db)
=> from fma in db.GetTable<AFF_CMS_FMA>()
where fma.IsArchived == false
orderby fma.SortOrder ascending
select fma);
public static Func<DataContext, int,IQueryable<AFF_CMS_FMA>>
getFmaById = CompiledQuery.Compile((DataContext db, int ID)
=> from fma in db.GetTable<AFF_CMS_FMA>()
where fma.ID == ID
select fma);
}
and finally this were im trying to get the save to happen to the db but no exeptions are throwns, yet the db does not change
public static bool saveEditedFmas(List<AFF_CMS_FMA> fmaToSaveList)
{
using (fmaDataContext db = new fmaDataContext())
{
using (TransactionScope ts = new TransactionScope())
{
try
{
foreach (AFF_CMS_FMA fmaItemToSave in fmaToSaveList)
{
AFF_CMS_FMA fmaItemToUpdate = clsCompiledQuery.getFmaById(db, fmaItemToSave.ID).ToList()[0];
fmaItemToUpdate = fmaItemToSave;
db.SubmitChanges();
}
return true;
}
catch (Exception ex)
{
Transaction.Current.Rollback();
return false;
}
}
}
}
I have checked and the table does contain a primary key in the designer. If i do the save from the btnSave_click function by passing a datacontext to the fetchAllActiveAssetsInFMA() then doing submitchanges on that context it works .. but im trying to abstract that from there.
thanks all in advance
Your not calling ts.Complete in function saveEditedFmas.
Also I would recommend calling db.SubmitChanges(); outside of the for loop. And why do you have a transaction in function fetchAllActiveAssetsInFMA? It's only fetching data right? And I'm not quite sure whats happening inside the for loop in save function, looks strange.
I think you should map the properties from fmaItemToSave to fmaItemToUpdate
foreach (var fmaItemToSave in fmaToSaveList)
{
var fmaItemToUpdate = clsCompiledQuery.getFmaById(db, fmaItemToSave.ID).First();
fmaItemToUpdate.Name = fmaItemToSave.Name;
fmaItemToUpdate.AssetID = fmaItemToSave.AssetID;
//And the rest of the properties
}
db.SubmitChanges();