I have a large block of code with several nested loops which needs to ultimately update many records in the database. I am trying to minimize the number of SaveChanges() calls to Entity Framework. Also note that we we are using the repository pattern.
Essentially I’m iterating a collection and need to update both the items in the collection and upon each iteration, another object retrieved from the db and contextualized by the item from the collection.
Sample code:
foreach (var outer in outerList)
{
obj = unit.GetRepository<MyObj>().Get(s =>
s.id = myId
).SingleOrDefault();
obj.value += outer.value;
outer.objId = obj.objId;
unit.GetRepository<MyOuterObj>().Update(outerObj);
unit.GetRepository<MyObj>().Update(obj);
}
unit.Save();
The call to Update() performs the following:
public virtual void Update(T entityToUpdate)
{
if(entityToUpdate is AuditModelBase)
{
var model = entityToUpdate as AuditModelBase;
model.UpdatedAt = DateTime.UtcNow;
}
DbSet.Attach(entityToUpdate);
Context.Entry(entityToUpdate).State = EntityState.Modified;
}
And the call to Save() of course performs the following:
_context.SaveChanges();
So my question is, as I’m reassigning obj to a different value each time through the loop, do I need Save() inside the foreach loop in order for all instances of “obj” to persist. Or does the DbSet.Attach(obj) ensure that each individual instance is updated regardless on what I do with the object in my loop.
Or perhaps a better way to ask this is:
Given that it looks like Attach() is pass-by-reference so therefore only my last obj will be updated, what are best practices with EF to accomplish this sort of thing (excluding the option of straight calls to SQL) ?
I don’t think you have to worry. Once you call
Attachon your object, it doesn’t matter whether you keep a reference to it yourself or not; it should be fine.The thing to keep in mind is that your object lives as long that it’s referenced by someone. So, it stands to reason that calling
Attachwould cause yourDbSetto reference your object, thus keeping it alive even after you don’t reference it anymore yourself.However, the best thing to do, in my opinion, is to just give it a try and see what happens!