public int Execute() { var autoDetectChanges = _ctx.Configuration.AutoDetectChangesEnabled; IEnumerable <IMergedData> mergeableEntities = null; Action endExecute = () => { _ctx.Configuration.AutoDetectChangesEnabled = autoDetectChanges; _ctx.IgnoreMergedData(mergeableEntities, false); }; using (new ActionDisposable(endExecute)) { // Suppress implicit DetectChanges() calls by EF, // e.g. called by SaveChanges(), ChangeTracker.Entries() etc. _ctx.Configuration.AutoDetectChangesEnabled = false; // Get all attached entries implementing IMergedData, // we need to ignore merge on them. Otherwise // EF's change detection may think that properties has changed // where they actually didn't. mergeableEntities = _ctx.GetMergeableEntitiesFromChangeTracker().ToArray(); // Now ignore merged data, otherwise merged data will be saved to database _ctx.IgnoreMergedData(mergeableEntities, true); // We must detect changes earlier in the process // before hooks are executed. Therefore we suppressed the // implicit DetectChanges() call by EF and call it here explicitly. _ctx.ChangeTracker.DetectChanges(); // Now get changed entries _changedEntries = _ctx.GetChangedEntries(); // pre IEnumerable <IHookedEntity> changedHookEntries; PreExecute(out changedHookEntries); // save var result = _ctx.SaveChangesCore(); // post PostExecute(changedHookEntries); return(result); } }
public SaveChangesOperation(ObjectContextBase ctx, IDbHookHandler hookHandler) { _ctx = ctx; _hookHandler = hookHandler; _changedEntries = ctx.GetChangedEntries().ToList(); }