/// <summary> /// This hard deletes this entity and any dependent entities that are already been cascade soft deleted /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="hardDeleteThisEntity">entity class with cascade soft delete interface. Mustn't be null</param> /// <param name="callSaveChanges">Defaults to calling SaveChanges. If set to false, then you must call SaveChanges</param> /// <returns>Returns a status. If no errors then Result contains the number of entities which were hard deleted, plus summary string in Message part</returns> public async Task <IStatusGeneric <int> > HardDeleteSoftDeletedEntriesAsync <TEntity>(TEntity hardDeleteThisEntity, bool callSaveChanges = true) where TEntity : class, TInterface { if (hardDeleteThisEntity == null) { throw new ArgumentNullException(nameof(hardDeleteThisEntity)); } var status = new StatusGenericHandler <int>(); if (_config.GetSoftDeleteValue.Compile().Invoke(hardDeleteThisEntity) == 0) { return(status.AddError($"This entry isn't {_config.TextSoftDeletedPastTense}.")); } //For reset you need to read every time because some of the collection might be soft deleted already var walker = new CascadeWalker <TInterface>(_context, _config, true, CascadeSoftDelWhatDoing.HardDeleteSoftDeleted, true); await walker.WalkEntitiesSoftDelete(hardDeleteThisEntity, 1); if (callSaveChanges) { await _context.SaveChangesAsync(); } return(ReturnSuccessFullResult(CascadeSoftDelWhatDoing.HardDeleteSoftDeleted, walker.NumFound)); }
/// <summary> /// This with cascade soft delete this entity and any dependent entities with the correct delete behaviour /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="softDeleteThisEntity">entity class with cascade soft delete interface. Mustn't be null</param> /// <param name="callSaveChanges">Defaults to calling SaveChanges. If set to false, then you must call SaveChanges</param> /// <returns>Returns a status. If no errors then Result contains the number of entities that had been cascaded deleted, plus summary string in Message part</returns> public async Task <IStatusGeneric <int> > SetCascadeSoftDeleteAsync <TEntity>(TEntity softDeleteThisEntity, bool callSaveChanges = true) where TEntity : class, TInterface { if (softDeleteThisEntity == null) { throw new ArgumentNullException(nameof(softDeleteThisEntity)); } _context.ThrowExceptionIfPrincipalOneToOne(softDeleteThisEntity); var status = new StatusGenericHandler <int>(); if (_config.GetSoftDeleteValue.Compile().Invoke(softDeleteThisEntity) != 0) { return(status.AddError($"This entry is already {_config.TextSoftDeletedPastTense}.")); } var walker = new CascadeWalker <TInterface>(_context, _config, true, CascadeSoftDelWhatDoing.SoftDelete, _config.ReadEveryTime); await walker.WalkEntitiesSoftDelete(softDeleteThisEntity, 1); if (callSaveChanges) { await _context.SaveChangesAsync(); } return(ReturnSuccessFullResult(CascadeSoftDelWhatDoing.SoftDelete, walker.NumFound)); }
/// <summary> /// This with cascade soft delete this entity and any dependent entities with the correct delete behaviour /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="softDeleteThisEntity">entity class with cascade soft delete interface. Mustn't be null</param> /// <param name="callSaveChanges">Defaults to calling SaveChanges. If set to false, then you must call SaveChanges</param> /// <returns>Returns a status. If no errors then Result contains the number of entities that had been cascaded deleted, plus summary string in Message part</returns> public IStatusGeneric <int> SetCascadeSoftDelete <TEntity>(TEntity softDeleteThisEntity, bool callSaveChanges = true) where TEntity : class, TInterface { if (softDeleteThisEntity == null) { throw new ArgumentNullException(nameof(softDeleteThisEntity)); } //If is a one-to-one entity we return an error var keys = _context.Entry(softDeleteThisEntity).Metadata.GetForeignKeys(); if (!keys.All(x => x.DependentToPrincipal?.IsCollection == true || x.PrincipalToDependent?.IsCollection == true)) { //This it is a one-to-one entity throw new InvalidOperationException("You cannot soft delete a one-to-one relationship. " + "It causes problems if you try to create a new version."); } var status = new StatusGenericHandler <int>(); if (_config.GetSoftDeleteValue.Compile().Invoke(softDeleteThisEntity) != 0) { return(status.AddError($"This entry is already {_config.TextSoftDeletedPastTense}.")); } var walker = new CascadeWalker <TInterface>(_context, _config, CascadeSoftDelWhatDoing.SoftDelete, _config.ReadEveryTime); walker.WalkEntitiesSoftDelete(softDeleteThisEntity, 1); if (callSaveChanges) { _context.SaveChanges(); } return(ReturnSuccessFullResult(CascadeSoftDelWhatDoing.SoftDelete, walker.NumFound)); }
/// <summary> /// This will result the cascade soft delete flag on this entity and any dependent entities with the correct delete behaviour and cascade level /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="resetSoftDeleteThisEntity">entity class with cascade soft delete interface. Mustn't be null</param> /// <param name="callSaveChanges">Defaults to calling SaveChanges. If set to false, then you must call SaveChanges</param> /// <returns>Returns a status. If no errors then Result contains the number of entities that had been reset, plus summary string in Message part</returns> public IStatusGeneric <int> ResetCascadeSoftDelete <TEntity>(TEntity resetSoftDeleteThisEntity, bool callSaveChanges = true) where TEntity : class, TInterface { if (resetSoftDeleteThisEntity == null) { throw new ArgumentNullException(nameof(resetSoftDeleteThisEntity)); } var status = new StatusGenericHandler <int>(); var currentDeleteLevel = _config.GetSoftDeleteValue.Compile().Invoke(resetSoftDeleteThisEntity); if (currentDeleteLevel == 0) { return(status.AddError($"This entry isn't {_config.TextSoftDeletedPastTense}.")); } if (currentDeleteLevel > 1) { return(status.AddError($"This entry was soft deleted {currentDeleteLevel - 1} " + $"level{(currentDeleteLevel > 2 ? "s" : "")} above here")); } //For reset you need to read every time because some of the collection might be soft deleted already var walker = new CascadeWalker <TInterface>(_context, _config, false, CascadeSoftDelWhatDoing.ResetSoftDelete, false); walker.WalkEntitiesSoftDelete(resetSoftDeleteThisEntity, 1).CheckSyncValueTaskWorked();; if (callSaveChanges) { _context.SaveChanges(); } return(ReturnSuccessFullResult(CascadeSoftDelWhatDoing.ResetSoftDelete, walker.NumFound)); }
/// <summary> /// This looks for this entity and any dependent entities that are already been cascade soft deleted and are valid to be hard deleted. /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="checkHardDeleteThisEntity">entity class with cascade soft delete interface. Mustn't be null</param> /// <returns>Returns a status. If no errors then Result contains the number of entities which are eligible for hard delete, plus summary string in Message part</returns> public IStatusGeneric <int> CheckCascadeSoftDelete <TEntity>(TEntity checkHardDeleteThisEntity) where TEntity : class, TInterface { if (checkHardDeleteThisEntity == null) { throw new ArgumentNullException(nameof(checkHardDeleteThisEntity)); } var status = new StatusGenericHandler <int>(); if (_config.GetSoftDeleteValue.Compile().Invoke(checkHardDeleteThisEntity) == 0) { return(status.AddError($"This entry isn't {_config.TextSoftDeletedPastTense}.")); } //For reset you need to read every time because some of the collection might be soft deleted already var walker = new CascadeWalker <TInterface>(_context, _config, false, CascadeSoftDelWhatDoing.CheckWhatWillDelete, _config.ReadEveryTime); var valueTask = walker.WalkEntitiesSoftDelete(checkHardDeleteThisEntity, 1); if (!valueTask.IsCompleted) { throw new InvalidOperationException("Can only run sync tasks"); } return(ReturnSuccessFullResult(CascadeSoftDelWhatDoing.CheckWhatWillDelete, walker.NumFound)); }