问题
What i want to do is simple. I have a list of parts in the db, and i want to delete/insert/update them according to an update list.
The main issue is that, when i want to replace an entry i can't attach it to the context because the older(to be updated) entry is already attached (by previous read call) and an exception is thrown.
I came around with 3 thoughts.
- Manually Detach the old entry and attach the new one (although changing entity state to detached still throws exception)
- Manually change the values of the old entry with the new ones
- Make the read call non track able (AsNoTracking()), this seems to work fine but i am concerned about impact on lazyloading.
Is there any functionality like "context.entry.replace(oldEntry,newEntry)" or any other proper way to do this?
IEnumerable<SoldPart> old = db.SoldParts.Where(sp=>sp.sessionId == sessionId);
var toDelete = old.Where(po=> !parts.Any(pu=>pu.id == po.id));
var toCreate = parts.Where(po => !old.Any(pu => pu.id == po.id));
var toUpdate = parts.Where(po => old.Any(pu => pu.id == po.id));
foreach (SoldPart item in toDelete)
{
db.SoldParts.Attach(item);
db.SoldParts.Remove(item);
}
foreach (SoldPart item in toCreate)
{
db.SoldParts.Add(item);
}
foreach (SoldPart item in toUpdate)
{
db.SoldParts.Attach(item);
db.Entry(item).State = EntityState.Modified;
}
db.SaveChanges();
回答1:
There is automatic way to update attached entity's values from detached one but it works only on scalar / complex properties. Not on navigation properties:
deb.Entry(oldEntry).CurrentValues.SetValues(newEntry);
来源:https://stackoverflow.com/questions/14471142/entity-framework-5-proper-method-to-replace-entry-in-context