/// <summary> /// Edits the items in the database. /// </summary> /// <param name="serviceProvider">The application service provider.</param> /// <param name="token">The cancellation token for the task.</param> public async Task EditAsync(IServiceProvider serviceProvider, CancellationToken token) { // Check if there weren't any valid items found. if (Items == null) { // Throw an exception. throw new TaskException("No valid items could be found with the provided data."); } // Check if the exception item should be shown. var showExceptionItem = Items.Count() > 1; // Get the total number of batches. var count = Math.Ceiling((double)Items.Count() / ApplicationDbContext.BatchSize); // Go over each batch. for (var index = 0; index < count; index++) { // Check if the cancellation was requested. if (token.IsCancellationRequested) { // Break. break; } // Get the items in the current batch. var batchItems = Items .Skip(index * ApplicationDbContext.BatchSize) .Take(ApplicationDbContext.BatchSize); // Get the IDs of the items in the current batch. var batchIds = batchItems .Where(item => !string.IsNullOrEmpty(item.Id)) .Select(item => item.Id); // Get the IDs of the related entities that appear in the current batch. var batchDatabaseIds = batchItems .Where(item => item.NodeCollectionDatabases != null) .Select(item => item.NodeCollectionDatabases) .SelectMany(item => item) .Where(item => item.Database != null) .Select(item => item.Database) .Where(item => !string.IsNullOrEmpty(item.Id)) .Select(item => item.Id) .Distinct(); var batchNodeIds = batchItems .Where(item => item.NodeCollectionNodes != null) .Select(item => item.NodeCollectionNodes) .SelectMany(item => item) .Where(item => item.Node != null) .Select(item => item.Node) .Where(item => !string.IsNullOrEmpty(item.Id)) .Select(item => item.Id) .Distinct(); // Define the list of items to get. var nodeCollections = new List <NodeCollection>(); var databases = new List <Database>(); var nodes = new List <Node>(); // Use a new scope. using (var scope = serviceProvider.CreateScope()) { // Use a new context instance. using var context = scope.ServiceProvider.GetRequiredService <ApplicationDbContext>(); // Get the items with the provided IDs. var items = context.NodeCollections .Where(item => !item.NodeCollectionDatabases.Any(item1 => item1.Database.DatabaseType.Name == "Generic")) .Where(item => batchIds.Contains(item.Id)); // Check if there were no items found. if (items == null || !items.Any()) { // Continue. continue; } // Get the items found. nodeCollections = items .ToList(); // Get the related entities that appear in the current batch. databases = context.Databases .Where(item => item.DatabaseType.Name != "Generic") .Where(item => batchDatabaseIds.Contains(item.Id)) .Distinct() .ToList(); nodes = context.Nodes .Where(item => !item.DatabaseNodes.Any(item1 => item1.Database.DatabaseType.Name == "Generic")) .Where(item => batchNodeIds.Contains(item.Id)) .ToList(); } // Get the IDs of the items. var nodeCollectionIds = nodeCollections .Select(item => item.Id); // Save the items to edit. var nodeCollectionsToEdit = new List <NodeCollection>(); // Go over each of the valid items. foreach (var batchItem in batchItems) { // Get the corresponding item. var nodeCollection = nodeCollections .FirstOrDefault(item => batchItem.Id == item.Id); // Check if there was no item found. if (nodeCollection == null) { // Continue. continue; } // Check if there were no node collection databases provided. if (batchItem.NodeCollectionDatabases == null || !batchItem.NodeCollectionDatabases.Any()) { // Throw an exception. throw new TaskException("There were no node collection databases provided.", showExceptionItem, batchItem); } // Get the node collection databases. var nodeCollectionDatabases = batchItem.NodeCollectionDatabases .Where(item => item.Database != null) .Where(item => !string.IsNullOrEmpty(item.Database.Id)) .Select(item => item.Database.Id) .Distinct() .Where(item => databases.Any(item1 => item1.Id == item)) .Select(item => new NodeCollectionDatabase { DatabaseId = item }); // Check if there were no node collection databases found. if (nodeCollectionDatabases == null || !nodeCollectionDatabases.Any()) { // Throw an exception. throw new TaskException("There were no node collection databases found.", showExceptionItem, batchItem); } // Check if there were no node collection nodes provided. if (batchItem.NodeCollectionNodes == null || !batchItem.NodeCollectionNodes.Any()) { // Throw an exception. throw new TaskException("There were no node collection nodes provided.", showExceptionItem, batchItem); } // Get the node collection nodes. var nodeCollectionNodes = batchItem.NodeCollectionNodes .Where(item => item.Node != null) .Where(item => !string.IsNullOrEmpty(item.Node.Id)) .Where(item => nodes.Any(item1 => item1.Id == item.Node.Id)) .Select(item => new NodeCollectionNode { NodeId = item.Node.Id }); // Check if there were no node collection nodes found. if (nodeCollectionNodes == null || !nodeCollectionNodes.Any()) { // Throw an exception. throw new TaskException("There were no node collection nodes found.", showExceptionItem, batchItem); } // Check if there were no node collection types provided. if (batchItem.NodeCollectionTypes == null || !batchItem.NodeCollectionTypes.Any()) { // Throw an exception. throw new TaskException("There were no node collection types provided.", showExceptionItem, batchItem); } // Get the node collection types. var nodeCollectionTypes = batchItem.NodeCollectionTypes .Select(item => item.Type) .Select(item => (Enum.TryParse <EnumerationNodeCollectionType>(item, out var type), type)) .Where(item => item.Item1) .Select(item => new NodeCollectionType { Type = item.Item2 }); // Check if there were no node collection types found. if (nodeCollectionTypes == null || !nodeCollectionTypes.Any()) { // Throw an exception. throw new TaskException("There were no node collection types found.", showExceptionItem, batchItem); } // Update the node collection. nodeCollection.Name = batchItem.Name; nodeCollection.Description = batchItem.Description; nodeCollection.NodeCollectionTypes = nodeCollectionTypes.ToList(); nodeCollection.NodeCollectionDatabases = nodeCollectionDatabases.ToList(); nodeCollection.NodeCollectionNodes = nodeCollectionNodes.ToList(); // Add the node collection to the list. nodeCollectionsToEdit.Add(nodeCollection); } // Delete the dependent entities. await NodeCollectionExtensions.DeleteDependentAnalysesAsync(nodeCollectionIds, serviceProvider, token); await NodeCollectionExtensions.DeleteDependentNetworksAsync(nodeCollectionIds, serviceProvider, token); // Delete the related entities. await NodeCollectionExtensions.DeleteRelatedEntitiesAsync <NodeCollectionType>(nodeCollectionIds, serviceProvider, token); await NodeCollectionExtensions.DeleteRelatedEntitiesAsync <NodeCollectionNode>(nodeCollectionIds, serviceProvider, token); await NodeCollectionExtensions.DeleteRelatedEntitiesAsync <NodeCollectionDatabase>(nodeCollectionIds, serviceProvider, token); // Update the items. await IEnumerableExtensions.EditAsync(nodeCollectionsToEdit, serviceProvider, token); } }
/// <summary> /// Deletes the items from the database. /// </summary> /// <param name="serviceProvider">The application service provider.</param> /// <param name="token">The cancellation token for the task.</param> public async Task DeleteAsync(IServiceProvider serviceProvider, CancellationToken token) { // Check if there weren't any valid items found. if (Items == null) { // Throw an exception. throw new TaskException("No valid items could be found with the provided data."); } // Get the total number of batches. var count = Math.Ceiling((double)Items.Count() / ApplicationDbContext.BatchSize); // Go over each batch. for (var index = 0; index < count; index++) { // Check if the cancellation was requested. if (token.IsCancellationRequested) { // Break. break; } // Get the items in the current batch. var batchItems = Items .Skip(index * ApplicationDbContext.BatchSize) .Take(ApplicationDbContext.BatchSize); // Get the IDs of the items in the current batch. var batchIds = batchItems.Select(item => item.Id); // Define the list of items to get. var nodeCollections = new List <NodeCollection>(); // Use a new scope. using (var scope = serviceProvider.CreateScope()) { // Use a new context instance. using var context = scope.ServiceProvider.GetRequiredService <ApplicationDbContext>(); // Get the items with the provided IDs. var items = context.NodeCollections .Where(item => batchIds.Contains(item.Id)); // Check if there were no items found. if (items == null || !items.Any()) { // Continue. continue; } // Get the items found. nodeCollections = items .ToList(); } // Get the IDs of the items. var nodeCollectionIds = nodeCollections .Select(item => item.Id); // Delete the dependent entities. await NodeCollectionExtensions.DeleteDependentAnalysesAsync(nodeCollectionIds, serviceProvider, token); await NodeCollectionExtensions.DeleteDependentNetworksAsync(nodeCollectionIds, serviceProvider, token); // Delete the related entities. await NodeCollectionExtensions.DeleteRelatedEntitiesAsync <NodeCollectionType>(nodeCollectionIds, serviceProvider, token); await NodeCollectionExtensions.DeleteRelatedEntitiesAsync <NodeCollectionNode>(nodeCollectionIds, serviceProvider, token); await NodeCollectionExtensions.DeleteRelatedEntitiesAsync <NodeCollectionDatabase>(nodeCollectionIds, serviceProvider, token); // Delete the items. await IEnumerableExtensions.DeleteAsync(nodeCollections, serviceProvider, token); } }
public async Task <IActionResult> OnPostAsync() { // Get the current user. var user = await _userManager.GetUserAsync(User); // Check if there aren't any IDs provided. if (Input.Ids == null || !Input.Ids.Any()) { // Display a message. TempData["StatusMessage"] = "Error: No or invalid IDs have been provided."; // Redirect to the index page. return(RedirectToPage("/Content/DatabaseTypes/PPI/Data/NodeCollections/Index")); } // Define the view. View = new ViewModel { Items = _context.NodeCollections .Where(item => item.NodeCollectionDatabases.Any(item1 => item1.Database.DatabaseType.Name == "PPI")) .Where(item => item.NodeCollectionDatabases.Any(item1 => item1.Database.IsPublic || item1.Database.DatabaseUsers.Any(item2 => item2.User == user))) .Where(item => Input.Ids.Contains(item.Id)) }; // Check if there weren't any items found. if (View.Items == null || !View.Items.Any()) { // Display a message. TempData["StatusMessage"] = "Error: No items have been found with the provided IDs, or you don't have access to them."; // Redirect to the index page. return(RedirectToPage("/Content/DatabaseTypes/PPI/Data/NodeCollections/Index")); } // Check if the reCaptcha is valid. if (!await _reCaptchaChecker.IsValid(Input.ReCaptchaToken)) { // Add an error to the model. ModelState.AddModelError(string.Empty, "The reCaptcha verification failed."); // Return the page. return(Page()); } // Check if the provided model isn't valid. if (!ModelState.IsValid) { // Add an error to the model. ModelState.AddModelError(string.Empty, "An error has been encountered. Please check again the input fields."); // Redisplay the page. return(Page()); } // Return the streamed file. return(new FileCallbackResult(MediaTypeNames.Application.Zip, async(zipStream, _) => { // Define a new ZIP archive. using var archive = new ZipArchive(zipStream, ZipArchiveMode.Create); // Check if the overview file should be added. if (true) { // Create a new entry in the archive and open it. using var stream = archive.CreateEntry($"Collections-List.txt", CompressionLevel.Fastest).Open(); // Write to the entry the corresponding file content. await NodeCollectionExtensions.WriteToStreamOverviewTextFileContent(View.Items.Select(item => item.Id), stream, _serviceProvider, HttpContext.Request.Scheme, HttpContext.Request.Host); } // Check which should be the format of the files within the archive. if (Input.FileFormat == "txt") { // Go over each of the node collections to download. foreach (var nodeCollection in View.Items) { // Create a new entry in the archive and open it. using var stream = archive.CreateEntry($"Collections-{nodeCollection.Name.Replace(" ", "-")}-{nodeCollection.Id}.txt", CompressionLevel.Fastest).Open(); // Write to the entry the corresponding file content. await nodeCollection.WriteToStreamTxtFileContent(stream, _serviceProvider); } } else if (Input.FileFormat == "json") { // Go over each of the node collections to download. foreach (var nodeCollection in View.Items) { // Create a new entry in the archive and open it. using var stream = archive.CreateEntry($"Collections-{nodeCollection.Name.Replace(" ", "-")}-{nodeCollection.Id}.json", CompressionLevel.Fastest).Open(); // Write to the entry the corresponding file content. await nodeCollection.WriteToStreamJsonFileContent(stream, _serviceProvider); } } else if (Input.FileFormat == "xlsx") { // Go over each of the node collections to download. foreach (var nodeCollection in View.Items) { // Create a new entry in the archive and open it. using var stream = archive.CreateEntry($"Collections-{nodeCollection.Name.Replace(" ", "-")}-{nodeCollection.Id}.xlsx", CompressionLevel.Fastest).Open(); // Write to the entry the corresponding file content. await nodeCollection.WriteToStreamXlsxFileContent(stream, _serviceProvider); } } }) { FileDownloadName = $"NetControl4BioMed-Collections-{DateTime.UtcNow:yyyyMMdd}.zip" });