Esempio n. 1
0
        /// <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 users = new List <User>();
                // 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.Users
                                .Where(item => batchIds.Contains(item.Id));
                    // Check if there were no items found.
                    if (items == null || !items.Any())
                    {
                        // Continue.
                        continue;
                    }
                    // Get the items found.
                    users = items
                            .ToList();
                }
                // Get the IDs of the items.
                var userIds = users
                              .Select(item => item.Id);
                // Define the dependent list of items to get.
                var analysisInputs = new List <AnalysisInputModel>();
                var networkInputs  = new List <NetworkInputModel>();
                // Use a new scope.
                using (var scope = serviceProvider.CreateScope())
                {
                    // Use a new context instance.
                    using var context = scope.ServiceProvider.GetRequiredService <ApplicationDbContext>();
                    // Get the items found.
                    var networks = context.Networks
                                   .Where(item => item.NetworkUsers.All(item1 => userIds.Contains(item1.User.Id)))
                                   .Select(item => item.NetworkEdges)
                                   .SelectMany(item => item)
                                   .Select(item => item.Network)
                                   .Distinct();
                    // Get the IDs of the dependent items.
                    analysisInputs = context.Analyses
                                     .Where(item => item.AnalysisUsers.All(item1 => userIds.Contains(item1.User.Id)) || item.AnalysisNetworks.Any(item1 => networks.Contains(item1.Network)))
                                     .Select(item => item.AnalysisEdges)
                                     .SelectMany(item => item)
                                     .Select(item => item.Analysis)
                                     .Distinct()
                                     .Select(item => new AnalysisInputModel
                    {
                        Id = item.Id
                    })
                                     .ToList();
                    networkInputs = networks
                                    .Select(item => new NetworkInputModel
                    {
                        Id = item.Id
                    })
                                    .ToList();
                }
                // Delete the dependent entities.
                await new AnalysesTask {
                    Items = analysisInputs
                }.DeleteAsync(serviceProvider, token);
                await new NetworksTask {
                    Items = networkInputs
                }.DeleteAsync(serviceProvider, token);
                // Delete the related entities.
                await UserExtensions.DeleteRelatedEntitiesAsync <AnalysisUser>(userIds, serviceProvider, token);

                await UserExtensions.DeleteRelatedEntitiesAsync <NetworkUser>(userIds, serviceProvider, token);

                await UserExtensions.DeleteRelatedEntitiesAsync <DatabaseUser>(userIds, serviceProvider, token);

                // Define a variable to store the error messages.
                var errorMessages = new List <string>();
                // Use a new scope.
                using (var scope = serviceProvider.CreateScope())
                {
                    // Use a new user manager instance.
                    var userManager = scope.ServiceProvider.GetRequiredService <UserManager <User> >();
                    // Go over each item.
                    foreach (var user in users)
                    {
                        // Delete it.
                        var result = await userManager.DeleteAsync(user);

                        // Check if the operation has failed.
                        if (!result.Succeeded)
                        {
                            // Define the exception messages.
                            var messages = result.Errors
                                           .Select(item => item.Description);
                            // Add the exception messages to the error messages.
                            errorMessages.AddRange(messages);
                        }
                    }
                }
                // Check if there have been any error messages.
                if (errorMessages.Any())
                {
                    // Throw an exception.
                    throw new TaskException(string.Join(" ", errorMessages));
                }
            }
        }