If you use the Attach
approach on an entity which has already changed, you will also need to tell EF that the entity is modified, after attaching it.
context.Specifications.Attach(entity);
context.Entry(entity).State = EntityState.Modified;
context.SaveChanges();
An alternative is to fetch (with tracking), then update the fields, and save:
var entity = context.Specifications.First(s => s.Id == 1234);
entity.Name = "Foo";
... other changes here
context.SaveChanges();
Another option is to make the changes to the entity after you have reattached it, e.g. as per here
context.Specifications.Attach(entity);
entity.Name = "Foo";
... other changes here
context.SaveChanges();
Edit
You can use generics with DbSet - either class, or method - as follows:
public void Update<TEntity>(TEntity entity)
{
DbContext.Set<TEntity>().Attach(entity);
DbContext.Entry(entity).State = EntityState.Modified;
DbContext.SaveChanges();
}
Edit : For updating of detached Parent / Child Graphs
For updating of simple / shallow parent-child relationships where efficiency and performance is not important, simply deleting all old children and reinserting the new ones is an easy (although ugly) solution.
However, for a more efficient scenario requires us to traverse the graph, detect changes, and then add newly inserted, update existing, ignore unchanged, and delete removed items from the Context
.
Slauma shows a great example of this here.
You might want to look at using GraphDiff, which can do all this leg work for you!
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…