private void OnBeforeDelete(object sender, OnBeforeDeleteEventArgs e) { // We're effectively disabled during actual deletion if (e.IsCommitPhase) { return; } // If we get here, we're traversing the delete graph. // Traversing means we're looping round doing a depth first cascade through relations, and we add each 'leaf' instance to the ordered list of objects to be deleted // But we're not actually goind any deleting during this phase, so we flag isHandled to block the delete at DataProvider level (means it skips the actual Delete call) e.IsHandled = true; // Initialise Init(e.Parameters); // Get the instance (e.Entity is only used to pass through the PK) var instance = Data.Get(e.Entity as TEntity, parameters: e.Parameters, skipSecurity: true); if (instance == null) { return; } // Ripple the delete through relations / subtypes var settings = new DataProviderDeleteSettings(e); settings.SkipSecurity = true; Ripple(instance, settings, e.Parameters); }
private void Ripple(TEntity instance, DataProviderDeleteSettings settings, Parameters parameters) { // Ripple each instance precisely once per DeleteStack traversal // (Note that this includes subtypes instances - i.e. the entire hierarchy is rippled from root call to RippleDelete) if (!DeleteStack.HasBeenRippledDuringCurrentTraversal(instance)) { if (!DeleteStack.IsResolved(instance)) { // Remember we've seen this instance DeleteStack.AddSeenObject(instance); // Count blockers before and after rippling in order to determine if instance can be added to the resolved list int numBlockers = DeleteStack.BlockersDuringCurrentTraversal.Count(); // Call virtual Ripple RippleDelete(instance, parameters, settings); // no errors => Can delete this object => Add to the resolved list if (numBlockers == DeleteStack.BlockersDuringCurrentTraversal.Count() && !DeleteStack.HasUnresolvedDependencies(instance)) { DeleteStack.MarkResolved(instance); // Do any deferred deletes DoDeferredDeletes(parameters, settings); } } } }
protected void Delete <T>(T item, Parameters parameters, DataProviderDeleteSettings settings, TEntity currentInstance) where T : IDataObject { if (!DeleteStack.IsResolved(item)) { var db = ApplicationSettings.Container.Resolve <IDataProvider <T> >(); db.Delete(item, settings.SecurityFilterExpression, settings.Context, parameters, settings.SkipSecurity); CheckResolved(currentInstance, item); NeedResync = true; } }
private void DoDeferredDeletes(Parameters parameters, DataProviderDeleteSettings settings) { if (_deferredDeleteItems.Any()) { try { foreach (var obj in _deferredDeleteItems) { dynamic db = ApplicationSettings.Container.Resolve <IEntityDataProvider>().GetDataProviderForEntity(obj) as IDataProvider; if (db != null) { db.Delete(obj, settings.SecurityFilterExpression, settings.Context, parameters, settings.SkipSecurity); } } } catch { _deferredDeleteItems.Clear(); throw; } } _deferredDeleteItems.Clear(); }
public override void RippleDelete(GOUserDataObject instance, Parameters parameters, DataProviderDeleteSettings settings) { // Set resync flag initially so that if any processing is done, it's on the latest copy of the data NeedResync = true; // GOUser.UserGroupItems (Cascade) { instance = Resync(instance); instance.LoadUserGroupItems(parameters, skipSecurity: true); foreach (var item in instance.UserGroupItems) { this.Delete(item, parameters, settings, instance); } } // GOUser.UserRoleItems (Cascade) { instance = Resync(instance); instance.LoadUserRoleItems(parameters, skipSecurity: true); foreach (var item in instance.UserRoleItems) { this.Delete(item, parameters, settings, instance); } } // GOUser.UserProfile (Reference) { instance = Resync(instance); instance.LoadUserProfile(parameters, skipSecurity: true); // We are the FK side entity and the PK side is optional, so no action required here (because when we're deleted, any reference(s) to UserProfile(s) is (are) deleted with us) } }
public abstract void RippleDelete(TEntity instance, Parameters parameters, DataProviderDeleteSettings settings);
public override void RippleDelete(GOUserGroupDataObject instance, Parameters parameters, DataProviderDeleteSettings settings) { }
public override void RippleDelete(PlaceToLocationDataObject instance, Parameters parameters, DataProviderDeleteSettings settings) { }
public override void RippleDelete(GORoleDataObject instance, Parameters parameters, DataProviderDeleteSettings settings) { // Set resync flag initially so that if any processing is done, it's on the latest copy of the data NeedResync = true; // GORole.GroupRoleItems (Cascade) { instance = Resync(instance); instance.LoadGroupRoleItems(parameters, skipSecurity: true); foreach (var item in instance.GroupRoleItems) { this.Delete(item, parameters, settings, instance); } } // GORole.UserRoleItems (Cascade) { instance = Resync(instance); instance.LoadUserRoleItems(parameters, skipSecurity: true); foreach (var item in instance.UserRoleItems) { this.Delete(item, parameters, settings, instance); } } }
public override void RippleDelete(VisitedPlaceDataObject instance, Parameters parameters, DataProviderDeleteSettings settings) { }
public override void RippleDelete(UserProfileDataObject instance, Parameters parameters, DataProviderDeleteSettings settings) { // Set resync flag initially so that if any processing is done, it's on the latest copy of the data NeedResync = true; // UserProfile.GOUser (Reference) { instance = Resync(instance); instance.LoadGOUser(parameters, skipSecurity: true); // We are the PK side entity in a OneToOne relationship, and the FK reference to us is optional. // So delete can proceed, but first we need to clear down the FK reference to us. var item = instance.GOUser; if (item != null && item.UserProfile != null) { item.UserProfile = null; Save(item); } } // UserProfile.VisitedPlaceItems (Protected) (i.e. Unable to delete UserProfile instances because VisitedPlaceItems.UserProfile is not optional and needs to be cleared first) { instance = Resync(instance); instance.LoadVisitedPlaceItems(parameters, skipSecurity: true); AddAnyBlockages("failDeleteProtected", instance, instance.VisitedPlaceItems); } }
public override void RippleDelete(PlaceDataObject instance, Parameters parameters, DataProviderDeleteSettings settings) { // Set resync flag initially so that if any processing is done, it's on the latest copy of the data NeedResync = true; // Place.PlaceToLocationItems (Protected) (i.e. Unable to delete Place instances because PlaceToLocationItems.Place is not optional and needs to be cleared first) { instance = Resync(instance); instance.LoadPlaceToLocationItems(parameters, skipSecurity: true); AddAnyBlockages("failDeleteProtected", instance, instance.PlaceToLocationItems); } // Place.VisitedPlaceItems (Reference) { instance = Resync(instance); instance.LoadVisitedPlaceItems(parameters, skipSecurity: true); foreach (var item in instance.VisitedPlaceItems) { if (item.Place != null) { item.Place = null; Save(item); } } } }
public override void RippleDelete(CountryDataObject instance, Parameters parameters, DataProviderDeleteSettings settings) { // Set resync flag initially so that if any processing is done, it's on the latest copy of the data NeedResync = true; // Country.VisitedPlaceItems (Reference) { instance = Resync(instance); instance.LoadVisitedPlaceItems(parameters, skipSecurity: true); foreach (var item in instance.VisitedPlaceItems) { if (item.Country != null) { item.Country = null; Save(item); } } } }
public override void RippleDelete(GOLoginHistoryDataObject instance, Parameters parameters, DataProviderDeleteSettings settings) { }
public override void RippleDelete(LocationDataObject instance, Parameters parameters, DataProviderDeleteSettings settings) { // Set resync flag initially so that if any processing is done, it's on the latest copy of the data NeedResync = true; // Location.PlaceToLocationItems (Protected) (i.e. Unable to delete Location instances because PlaceToLocationItems.Location is not optional and needs to be cleared first) { instance = Resync(instance); instance.LoadPlaceToLocationItems(parameters, skipSecurity: true); AddAnyBlockages("failDeleteProtected", instance, instance.PlaceToLocationItems); } }