How to update a second ObjectContext with deletions made on first one
I have a many-to-many relation Patients - PatientDevices - Devices and a basic edmx-model of it (no poco, automatic generation). PatientDevices is generated as an entity, because it has more columns than the foreign keys.
When I create two ObjectContexts and add a new PatientDevice into the first one, the second one has it also. When deleting this relation from the first one, it is still in the second context:
var entities1 = new TherapyDatabaseDevEntities();
var entities2 = new TherapyDatabaseDevEntities();
entities1.PatientDevices.AddObject(new PatientDevice
{
Patient = entities1.Patients.First(),
Device = entities1.Devices.First()
});
entities1.SaveChanges();
var relation1a = entities1.Patients.First().PatientDevices.ToList();
var relation2a = entities2.Patients.First().PatientDevices.ToList();
entities1.PatientDevices.DeleteObject(entities1.PatientDevices.ToList().Last());
entities1.SaveChanges();
var relation1b = entities1.Patients.First().PatientDevices.ToList();
var relation2b = entities2.Patients.First().PatientDevices.ToList();
relation1a and relation2a both have one entry. relation1b has no entry, but relation2b has one entry. Even if working with refreshes before the query:
entities2.Refresh(Refresh开发者_如何学GoMode.StoreWins, entities2.Patients);
entities2.Refresh(RefreshMode.StoreWins, entities2.PatientDevices);
entities2.Refresh(RefreshMode.StoreWins, entities2.Devices);
var relation1b = entities1.Patients.First().PatientDevices.ToList();
// still 1 entry
var relation2b = entities2.Patients.First().PatientDevices.ToList();
Is there a possibility to bring the second context up to date or do I have to create another ObjectContext?
Edit
I found out that if I do this:
entities2.Refresh(RefreshMode.StoreWins, entities2.Patients.First().PatientDevices);
the relation gets updated properly. It's a pity that without the refresh entities2.PatientDevices does not contain the deleted object anymore, but entities2.Patients.First().PatientDevices still has it.
Is this intended behavior?
If you must have multiple contexts and work directly with your entities, have a look at the Attach and Detach methods, which as the names suggest are used to associate/dissociate an object from the context it was retrieved from. Note though that these methods only detatch the object you pass as an argument, not associated objects, so you'd probably have to walk through the connected objects detatching each one, which is messy.
var entities1 = new TherapyDatabaseDevEntities();
var patient1 = entities1.Patients.Single(p => p.Id = 12345);
entities1.Detach(patient1);
//loop through associated entities calling Detach on each
var entities2 = new TherapyDatabaseDevEntities();
entities2.Attach(patient1);
//loop through associated entities calling Attach on each
My preference would be to use viewmodels so that you aren't editing the entities directly, but representations of them. When a user explicitly saves an object, retrieve that object and update the changes from that object only on a fresh context.
var entities1 = new TherapyDatabaseDevEntities();
var patient1 = entities1.Patients.Single(p => p.Id = 12345);
... dispose of your context, it's no longer needed, and make your changes here
var entities2 = new TherapyDatabaseDevEntities();
var patient2 = entities2.Patients.Single(p => p.Id = 12345);
patient2.Property1 = patient1.Property1;
... update with other changes (there's ways to make this code cleaner, just showing simplest example)
entities2.SaveChanges();
entities2.Dispose();
Some reference material on Attach/Detach here - http://msdn.microsoft.com/en-us/library/bb896271.aspx
Do a search on entity framework context lifetimes, there's a lot of discussion on this subject which might help you decide on a route that suits your needs.
精彩评论