Updating records in foreach loop in Entity Framework 6
10,309
As discussed in the comments, since Entity Framework context is (internally) employing the Unit of Work pattern, you need to call SaveChanges()
only once and only after you've done modifying all the items.
More on MSDN
Author by
Piotr Truszkowski
Updated on June 04, 2022Comments
-
Piotr Truszkowski almost 2 years
I have a problem with updating records in a foreach loop. I have a method that exports files from SQL Table and saves them on a net share:
public static void SyncOpportunity() { using (var ctx = new BPMOnline74Entities()) { logger.Debug("Importing files from Opportunities."); var oppFiles = from o in ctx.OpportunityFile where SqlFunctions.DataLength(o.Data) > 0 && o.ServiceProcessed == false select o; foreach (OpportunityFile opp in oppFiles) { logger.Debug(string.Format("{0} is being imported.", opp.Name)); string fileName=""; if (opp.OpportunityId == null) { fileName = "E:\\BPM\\Opportunity\\"; logger.Error("File not bound to any DB object. Saved in E:\\BPM\\Opportunity."); } else { try { fileName = PathInfo.GetPath("Opportunity", (Guid)opp.OpportunityId); } catch (Exception ex) { logger.Error(ex.Message.ToString()); } } try { File.WriteAllBytes(fileName + opp.Name, opp.Data); logger.Debug(string.Format("{0} was exported from SQL.", opp.Name)); opp.ServiceProcessed = true; ctx.Entry(opp).State = System.Data.Entity.EntityState.Modified; ctx.SaveChanges(); } catch(Exception ex) { logger.Error(ex.Message.ToString()); } } logger.Debug(string.Format("Imported {0} files.", oppFiles.Count().ToString())); } logger.Debug("Disposing SyncOpportunity."); }
After the file is successfully exported from SQL I want to update the record's "ServiceProcessed" field to true so it won't be selected on the next iteration of my service. The problem is that my method doesn't update the DB and always "catches" all of my records.