public bool Remove(Principal principal) { string str = null; bool flag; this.CheckDisposed(); if (principal != null) { StoreCtx storeCtxToUse = this.owningGroup.GetStoreCtxToUse(); if (storeCtxToUse == null || storeCtxToUse.CanGroupMemberBeRemoved(this.owningGroup, principal, out str)) { if (!this.insertedValuesPending.Contains(principal)) { flag = this.Contains(principal); if (flag) { this.MarkChange(); this.removedValuesPending.Add(principal); this.insertedValuesCompleted.Remove(principal); } } else { this.MarkChange(); this.insertedValuesPending.Remove(principal); flag = true; if (!this.removedValuesCompleted.Contains(principal)) { this.removedValuesCompleted.Add(principal); } } return(flag); } else { throw new InvalidOperationException(str); } } else { throw new ArgumentNullException("principal"); } }
public bool Remove(Principal principal) { CheckDisposed(); if (principal == null) { throw new ArgumentNullException("principal"); } // Ask the StoreCtx to verify that this member can be removed. Right now, the only // reason it couldn't is if it's actually a member by virtue of its primaryGroupId // pointing to this group. // // If storeCtxToUse == null, then we must be unpersisted, in which case there clearly // can't be any such primary group members pointing to this group on the store. StoreCtx storeCtxToUse = _owningGroup.GetStoreCtxToUse(); string explanation; Debug.Assert(storeCtxToUse != null || _owningGroup.unpersisted == true); if ((storeCtxToUse != null) && (!storeCtxToUse.CanGroupMemberBeRemoved(_owningGroup, principal, out explanation))) { throw new InvalidOperationException(explanation); } bool removed = false; // If the value was previously inserted, we just remove it from insertedValuesPending. if (_insertedValuesPending.Contains(principal)) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "PrincipalCollection", "Remove: removing from insertedValuesPending"); MarkChange(); _insertedValuesPending.Remove(principal); removed = true; // If they did a Remove(x) --> Save() --> Add(x) --> Remove(x), we'll end up with x in neither // the ResultSet or the removedValuesCompleted list. This is bad. Avoid that by adding x // back to the removedValuesCompleted list here. // // At worst, we end up with x on the removedValuesCompleted list even though it's not even in // resultSet. That's not a problem. The only thing we use the removedValuesCompleted list for // is deciding which values in resultSet to skip, anyway. if (!_removedValuesCompleted.Contains(principal)) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "PrincipalCollection", "Remove: adding to removedValuesCompleted"); _removedValuesCompleted.Add(principal); } } else { // They're trying to remove a already-persisted value. We add it to the // removedValues list. Then, if it's already been loaded into insertedValuesCompleted, // we remove it from insertedValuesCompleted. removed = Contains(principal); GlobalDebug.WriteLineIf(GlobalDebug.Info, "PrincipalCollection", "Remove: making it a pending remove, removed={0}", removed); if (removed) { MarkChange(); _removedValuesPending.Add(principal); // in case it's the result of a previous-but-already-committed insert _insertedValuesCompleted.Remove(principal); } } return(removed); }