/// <summary>
        /// Creates 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 CreateAsync(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);
                // Check if any of the IDs are repeating in the list.
                if (batchIds.Distinct().Count() != batchIds.Count())
                {
                    // Throw an exception.
                    throw new TaskException("Two or more of the manually provided IDs are duplicated.");
                }
                // 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 validBatchIds = new List <string>();
                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 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 valid IDs, that do not appear in the database.
                    validBatchIds = batchIds
                                    .Except(context.NodeCollections
                                            .Where(item => batchIds.Contains(item.Id))
                                            .Select(item => item.Id))
                                    .ToList();
                }
                // Save the items to add.
                var nodeCollectionsToAdd = new List <NodeCollection>();
                // Go over each of the items.
                foreach (var batchItem in batchItems)
                {
                    // Check if the ID of the item is not valid.
                    if (!string.IsNullOrEmpty(batchItem.Id) && !validBatchIds.Contains(batchItem.Id))
                    {
                        // 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);
                    }
                    // Define the new node collection.
                    var nodeCollection = new NodeCollection
                    {
                        DateTimeCreated         = DateTime.UtcNow,
                        Name                    = batchItem.Name,
                        Description             = batchItem.Description,
                        NodeCollectionTypes     = nodeCollectionTypes.ToList(),
                        NodeCollectionDatabases = nodeCollectionDatabases.ToList(),
                        NodeCollectionNodes     = nodeCollectionNodes.ToList()
                    };
                    // Check if there is any ID provided.
                    if (!string.IsNullOrEmpty(batchItem.Id))
                    {
                        // Assign it to the node collection.
                        nodeCollection.Id = batchItem.Id;
                    }
                    // Add the new node collection to the list.
                    nodeCollectionsToAdd.Add(nodeCollection);
                }
                // Create the items.
                await IEnumerableExtensions.CreateAsync(nodeCollectionsToAdd, serviceProvider, token);
            }
        }
        /// <summary>
        /// Creates 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 CreateAsync(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 related entities that appear in the current batch.
                var batchAnalysisIds = batchItems
                                       .Where(item => item.Analysis != null)
                                       .Select(item => item.Analysis)
                                       .Where(item => !string.IsNullOrEmpty(item.Id))
                                       .Select(item => item.Id)
                                       .Distinct();
                var batchUserIds = batchItems
                                   .Where(item => item.User != null)
                                   .Select(item => item.User)
                                   .Where(item => !string.IsNullOrEmpty(item.Id))
                                   .Select(item => item.Id)
                                   .Distinct();
                // Define the list of items to get.
                var analyses = new List <Analysis>();
                var users    = new List <User>();
                // Create a new scope.
                using (var scope = serviceProvider.CreateScope())
                {
                    // Use a new context instance.
                    using var context = scope.ServiceProvider.GetRequiredService <ApplicationDbContext>();
                    // Get the related entities that appear in the current batch.
                    analyses = context.Analyses
                               .Where(item => batchAnalysisIds.Contains(item.Id))
                               .ToList();
                    users = context.Users
                            .Where(item => batchUserIds.Contains(item.Id))
                            .ToList();
                }
                // Save the items to add.
                var analysisUsersToAdd = new List <AnalysisUser>();
                // Go over each item in the current batch.
                foreach (var batchItem in batchItems)
                {
                    // Check if there was no analysis provided.
                    if (batchItem.Analysis == null || string.IsNullOrEmpty(batchItem.Analysis.Id))
                    {
                        // Throw an exception.
                        throw new TaskException("There was no analysis provided.", showExceptionItem, batchItem);
                    }
                    // Get the analysis.
                    var analysis = analyses
                                   .FirstOrDefault(item => item.Id == batchItem.Analysis.Id);
                    // Check if there was no analysis found.
                    if (analysis == null)
                    {
                        // Throw an exception.
                        throw new TaskException($"There was no analysis found.", showExceptionItem, batchItem);
                    }
                    // Check if there was no user provided.
                    if (batchItem.User == null || string.IsNullOrEmpty(batchItem.User.Id))
                    {
                        // Throw an exception.
                        throw new TaskException("There was no user provided.", showExceptionItem, batchItem);
                    }
                    // Get the user.
                    var user = users
                               .FirstOrDefault(item => item.Id == batchItem.User.Id);
                    // Check if there was no user found.
                    if (user == null)
                    {
                        // Throw an exception.
                        throw new TaskException($"There was no user found.", showExceptionItem, batchItem);
                    }
                    // Define the new item.
                    var analysisUser = new AnalysisUser
                    {
                        DateTimeCreated = DateTime.UtcNow,
                        AnalysisId      = analysis.Id,
                        UserId          = user.Id
                    };
                    // Add the item to the list.
                    analysisUsersToAdd.Add(analysisUser);
                }
                // Create the items.
                await IEnumerableExtensions.CreateAsync(analysisUsersToAdd, serviceProvider, token);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Creates 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 CreateAsync(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);
                var batchNames = batchItems
                                 .Where(item => !string.IsNullOrEmpty(item.Name))
                                 .Select(item => item.Name)
                                 .Distinct();
                // Check if any of the IDs are repeating in the list.
                if (batchIds.Distinct().Count() != batchIds.Count())
                {
                    // Throw an exception.
                    throw new TaskException("Two or more of the manually provided IDs are duplicated.");
                }
                // Get the IDs of the related entities that appear in the current batch.
                var batchDatabaseIds = batchItems
                                       .Where(item => item.Database != null)
                                       .Select(item => item.Database)
                                       .Where(item => !string.IsNullOrEmpty(item.Id))
                                       .Select(item => item.Id)
                                       .Distinct();
                // Define the list of items to get.
                var databases = new List <Database>();
                var existingDatabaseEdgeFieldNames = new List <string>();
                var validBatchIds = new List <string>();
                // Use a new scope.
                using (var scope = serviceProvider.CreateScope())
                {
                    // Use a new context instance.
                    using var context = scope.ServiceProvider.GetRequiredService <ApplicationDbContext>();
                    // Get the related entities that appear in the current batch.
                    databases = context.Databases
                                .Include(item => item.DatabaseType)
                                .Where(item => batchDatabaseIds.Contains(item.Id))
                                .ToList();
                    existingDatabaseEdgeFieldNames = context.DatabaseEdgeFields
                                                     .Where(item => batchNames.Contains(item.Name))
                                                     .Select(item => item.Name)
                                                     .ToList();
                    // Get the valid IDs, that do not appear in the database.
                    validBatchIds = batchIds
                                    .Except(context.DatabaseEdgeFields
                                            .Where(item => batchIds.Contains(item.Id))
                                            .Select(item => item.Id))
                                    .ToList();
                }
                // Save the items to add.
                var databaseEdgeFieldsToAdd = new List <DatabaseEdgeField>();
                // Go over each item in the current batch.
                foreach (var batchItem in batchItems)
                {
                    // Check if the ID of the item is not valid.
                    if (!string.IsNullOrEmpty(batchItem.Id) && !validBatchIds.Contains(batchItem.Id))
                    {
                        // Continue.
                        continue;
                    }
                    // Check if there is another database edge field with the same name.
                    if (existingDatabaseEdgeFieldNames.Any(item => item == batchItem.Name) || databaseEdgeFieldsToAdd.Any(item => item.Name == batchItem.Name))
                    {
                        // Throw an exception.
                        throw new TaskException("A database edge field with the same name already exists.", showExceptionItem, batchItem);
                    }
                    // Check if there was no database provided.
                    if (batchItem.Database == null || string.IsNullOrEmpty(batchItem.Database.Id))
                    {
                        // Throw an exception.
                        throw new TaskException("There was no database provided.", showExceptionItem, batchItem);
                    }
                    // Get the database.
                    var database = databases
                                   .FirstOrDefault(item => item.Id == batchItem.Database.Id);
                    // Check if there was no database found.
                    if (database == null)
                    {
                        // Throw an exception.
                        throw new TaskException("There was no database found.", showExceptionItem, batchItem);
                    }
                    // Check if the database is generic.
                    if (database.DatabaseType.Name == "Generic")
                    {
                        // Throw an exception.
                        throw new TaskException("The database edge field can't be generic.", showExceptionItem, batchItem);
                    }
                    // Define the new item.
                    var databaseEdgeField = new DatabaseEdgeField
                    {
                        DateTimeCreated = DateTime.UtcNow,
                        Name            = batchItem.Name,
                        Description     = batchItem.Description,
                        Url             = batchItem.Url,
                        IsSearchable    = batchItem.IsSearchable,
                        DatabaseId      = database.Id
                    };
                    // Check if there is any ID provided.
                    if (!string.IsNullOrEmpty(batchItem.Id))
                    {
                        // Assign it to the item.
                        database.Id = batchItem.Id;
                    }
                    // Add the item to the list.
                    databaseEdgeFieldsToAdd.Add(databaseEdgeField);
                }
                // Create the items.
                await IEnumerableExtensions.CreateAsync(databaseEdgeFieldsToAdd, serviceProvider, token);
            }
        }
        /// <summary>
        /// Creates 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 CreateAsync(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 related entities that appear in the current batch.
                var batchNetworkIds = batchItems
                                      .Where(item => item.Network != null)
                                      .Select(item => item.Network)
                                      .Where(item => !string.IsNullOrEmpty(item.Id))
                                      .Select(item => item.Id)
                                      .Distinct();
                var batchUserEmails = batchItems
                                      .Where(item => !string.IsNullOrEmpty(item.Email))
                                      .Select(item => item.Email)
                                      .Distinct();
                // Define the list of items to get.
                var networks = new List <Network>();
                var users    = new List <User>();
                // Create a new scope.
                using (var scope = serviceProvider.CreateScope())
                {
                    // Use a new context instance.
                    using var context = scope.ServiceProvider.GetRequiredService <ApplicationDbContext>();
                    // Get the related entities that appear in the current batch.
                    networks = context.Networks
                               .Where(item => batchNetworkIds.Contains(item.Id))
                               .ToList();
                    users = context.Users
                            .Where(item => batchUserEmails.Contains(item.Email))
                            .ToList();
                }
                // Save the items to add.
                var networkUserInvitationsToAdd = new List <NetworkUserInvitation>();
                // Go over each item in the current batch.
                foreach (var batchItem in batchItems)
                {
                    // Check if there was no network provided.
                    if (batchItem.Network == null || string.IsNullOrEmpty(batchItem.Network.Id))
                    {
                        // Throw an exception.
                        throw new TaskException("There was no network provided.", showExceptionItem, batchItem);
                    }
                    // Get the network.
                    var network = networks
                                  .FirstOrDefault(item => item.Id == batchItem.Network.Id);
                    // Check if there was no network found.
                    if (network == null)
                    {
                        // Throw an exception.
                        throw new TaskException("There was no network found.", showExceptionItem, batchItem);
                    }
                    // Check if there was no e-mail provided.
                    if (string.IsNullOrEmpty(batchItem.Email))
                    {
                        // Throw an exception.
                        throw new TaskException("There was no e-mail provided.", showExceptionItem, batchItem);
                    }
                    // Try to get the user.
                    var user = users
                               .FirstOrDefault(item => item.Email == batchItem.Email);
                    // Check if there was a user found.
                    if (user != null)
                    {
                        // Throw an exception.
                        throw new TaskException("The user with the provided e-mail already exists.", showExceptionItem, batchItem);
                    }
                    // Define the new item.
                    var networkUserInvitation = new NetworkUserInvitation
                    {
                        DateTimeCreated = DateTime.UtcNow,
                        NetworkId       = network.Id,
                        Email           = batchItem.Email
                    };
                    // Add the item to the list.
                    networkUserInvitationsToAdd.Add(networkUserInvitation);
                }
                // Create the items.
                await IEnumerableExtensions.CreateAsync(networkUserInvitationsToAdd, serviceProvider, token);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Creates 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 CreateAsync(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);
                // Check if any of the IDs are repeating in the list.
                if (batchIds.Distinct().Count() != batchIds.Count())
                {
                    // Throw an exception.
                    throw new TaskException("Two or more of the manually provided IDs are duplicated.");
                }
                // Get the IDs of the related entities that appear in the current batch.
                var batchDatabaseIds = batchItems
                                       .Where(item => item.DatabaseEdges != null)
                                       .Select(item => item.DatabaseEdges)
                                       .SelectMany(item => item)
                                       .Where(item => item.Database != null)
                                       .Select(item => item.Database)
                                       .Where(item => !string.IsNullOrEmpty(item.Id))
                                       .Select(item => item.Id)
                                       .Distinct();
                var batchDatabaseEdgeFieldIds = batchItems
                                                .Where(item => item.DatabaseEdgeFieldEdges != null)
                                                .Select(item => item.DatabaseEdgeFieldEdges)
                                                .SelectMany(item => item)
                                                .Where(item => item.DatabaseEdgeField != null)
                                                .Select(item => item.DatabaseEdgeField)
                                                .Where(item => !string.IsNullOrEmpty(item.Id))
                                                .Select(item => item.Id)
                                                .Distinct();
                var batchNodeIds = batchItems
                                   .Where(item => item.EdgeNodes != null)
                                   .Select(item => item.EdgeNodes)
                                   .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 validBatchIds      = new List <string>();
                var databaseEdgeFields = new List <DatabaseEdgeField>();
                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 related entities that appear in the current batch.
                    databaseEdgeFields = context.DatabaseEdgeFields
                                         .Where(item => item.Database.DatabaseType.Name != "Generic")
                                         .Where(item => batchDatabaseEdgeFieldIds.Contains(item.Id))
                                         .ToList();
                    databases = context.Databases
                                .Where(item => item.DatabaseType.Name != "Generic")
                                .Where(item => batchDatabaseIds.Contains(item.Id))
                                .Concat(context.DatabaseEdgeFields
                                        .Where(item => item.Database.DatabaseType.Name != "Generic")
                                        .Where(item => batchDatabaseEdgeFieldIds.Contains(item.Id))
                                        .Select(item => item.Database))
                                .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 valid IDs, that do not appear in the database.
                    validBatchIds = batchIds
                                    .Except(context.Edges
                                            .Where(item => batchIds.Contains(item.Id))
                                            .Select(item => item.Id))
                                    .ToList();
                }
                // Save the items to add.
                var edgesToAdd = new List <Edge>();
                // Go over each of the items.
                foreach (var batchItem in batchItems)
                {
                    // Check if the ID of the item is not valid.
                    if (!string.IsNullOrEmpty(batchItem.Id) && !validBatchIds.Contains(batchItem.Id))
                    {
                        // Continue.
                        continue;
                    }
                    // Check if there were no edge nodes provided.
                    if (batchItem.EdgeNodes == null || !batchItem.EdgeNodes.Any())
                    {
                        // Throw an exception.
                        throw new TaskException("There were no edge nodes provided.", showExceptionItem, batchItem);
                    }
                    // Get the edge nodes.
                    var edgeNodes = batchItem.EdgeNodes
                                    .Where(item => item.Node != null)
                                    .Where(item => !string.IsNullOrEmpty(item.Node.Id))
                                    .Where(item => item.Type == "Source" || item.Type == "Target")
                                    .Select(item => (item.Node.Id, item.Type))
                                    .Distinct()
                                    .Where(item => nodes.Any(item1 => item1.Id == item.Item1))
                                    .Select(item => new EdgeNode
                    {
                        NodeId = item.Item1,
                        Type   = EnumerationExtensions.GetEnumerationValue <EdgeNodeType>(item.Item2)
                    });
                    // Check if there were no edge nodes found.
                    if (edgeNodes == null || !edgeNodes.Any(item => item.Type == EdgeNodeType.Source) || !edgeNodes.Any(item => item.Type == EdgeNodeType.Target))
                    {
                        // Throw an exception.
                        throw new TaskException("There were no edge nodes found.", showExceptionItem, batchItem);
                    }
                    // Check if there were no database edges or database edge field edges provided.
                    if ((batchItem.DatabaseEdges == null || !batchItem.DatabaseEdges.Any()) && (batchItem.DatabaseEdgeFieldEdges == null || !batchItem.DatabaseEdgeFieldEdges.Any()))
                    {
                        // Throw an exception.
                        throw new TaskException("There were no database edges or database edge field edges provided.", showExceptionItem, batchItem);
                    }
                    // Get the database edge field edges.
                    var databaseEdgeFieldEdges = batchItem.DatabaseEdgeFieldEdges != null?
                                                 batchItem.DatabaseEdgeFieldEdges
                                                 .Where(item => item.DatabaseEdgeField != null)
                                                 .Where(item => !string.IsNullOrEmpty(item.DatabaseEdgeField.Id))
                                                 .Where(item => !string.IsNullOrEmpty(item.Value))
                                                 .Select(item => (item.DatabaseEdgeField.Id, item.Value))
                                                 .Distinct()
                                                 .Where(item => databaseEdgeFields.Any(item1 => item1.Id == item.Item1))
                                                 .Select(item => new DatabaseEdgeFieldEdge
                    {
                        DatabaseEdgeFieldId = item.Item1,
                        Value = item.Item2
                    }) :
                                                     Enumerable.Empty <DatabaseEdgeFieldEdge>();

                    // Get the database edges.
                    var databaseEdgeFieldIds = databaseEdgeFieldEdges
                                               .Select(item => item.DatabaseEdgeFieldId)
                                               .Distinct();
                    var currentDatabaseEdgeFields = databaseEdgeFields
                                                    .Where(item => databaseEdgeFieldIds.Contains(item.Id));
                    var databaseEdges = batchItem.DatabaseEdges != null?
                                        batchItem.DatabaseEdges
                                        .Where(item => item.Database != null)
                                        .Where(item => !string.IsNullOrEmpty(item.Database.Id))
                                        .Select(item => item.Database.Id)
                                        .Concat(currentDatabaseEdgeFields
                                                .Select(item => item.Database.Id))
                                        .Distinct()
                                        .Where(item => databases.Any(item1 => item1.Id == item))
                                        .Select(item => new DatabaseEdge
                    {
                        DatabaseId = item,
                    }) :
                                            Enumerable.Empty <DatabaseEdge>();

                    // Check if there were no database edges found.
                    if (databaseEdges == null || !databaseEdges.Any())
                    {
                        // Throw an exception.
                        throw new TaskException("There were no database edges found.", showExceptionItem, batchItem);
                    }
                    // Define the new edge.
                    var edge = new Edge
                    {
                        DateTimeCreated = DateTime.UtcNow,
                        Name            = string.Concat(nodes.First(item => item.Id == edgeNodes.First(item => item.Type == EdgeNodeType.Source).NodeId).Name, " - ", nodes.First(item => item.Id == edgeNodes.First(item => item.Type == EdgeNodeType.Target).NodeId).Name),
                        Description     = batchItem.Description,
                        EdgeNodes       = new List <EdgeNode>
                        {
                            edgeNodes.First(item => item.Type == EdgeNodeType.Source),
                            edgeNodes.First(item => item.Type == EdgeNodeType.Target)
                        },
                        DatabaseEdgeFieldEdges = databaseEdgeFieldEdges.ToList(),
                        DatabaseEdges          = databaseEdges.ToList()
                    };
                    // Check if there is any ID provided.
                    if (!string.IsNullOrEmpty(batchItem.Id))
                    {
                        // Assign it to the node.
                        edge.Id = batchItem.Id;
                    }
                    // Add the new node to the list.
                    edgesToAdd.Add(edge);
                }
                // Create the items.
                await IEnumerableExtensions.CreateAsync(edgesToAdd, serviceProvider, token);
            }
        }
        /// <summary>
        /// Creates 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 <IEnumerable <string> > CreateAsync(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);
            // Save the IDs of the created items.
            var ids = Enumerable.Empty <string>();

            // 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);
                // Check if any of the IDs are repeating in the list.
                if (batchIds.Distinct().Count() != batchIds.Count())
                {
                    // Throw an exception.
                    throw new TaskException("One or more of the manually provided IDs are duplicated.");
                }
                // Get the IDs of the related entities that appear in the current batch.
                var batchUserIds = batchItems
                                   .Where(item => item.NetworkUsers != null)
                                   .Select(item => item.NetworkUsers)
                                   .SelectMany(item => item)
                                   .Where(item => item.User != null)
                                   .Select(item => item.User)
                                   .Where(item => !string.IsNullOrEmpty(item.Id))
                                   .Select(item => item.Id)
                                   .Distinct();
                var batchDatabaseIds = batchItems
                                       .Where(item => item.NetworkDatabases != null)
                                       .Select(item => item.NetworkDatabases)
                                       .SelectMany(item => item)
                                       .Where(item => item.Database != null)
                                       .Select(item => item.Database)
                                       .Where(item => !string.IsNullOrEmpty(item.Id))
                                       .Select(item => item.Id)
                                       .Distinct();
                var batchNodeCollectionIds = batchItems
                                             .Where(item => item.NetworkNodeCollections != null)
                                             .Select(item => item.NetworkNodeCollections)
                                             .SelectMany(item => item)
                                             .Where(item => item.NodeCollection != null)
                                             .Select(item => item.NodeCollection)
                                             .Where(item => !string.IsNullOrEmpty(item.Id))
                                             .Select(item => item.Id)
                                             .Distinct();
                // Define the list of items to get.
                var users           = new List <User>();
                var databases       = new List <Database>();
                var nodeCollections = new List <NodeCollection>();
                var validBatchIds   = new List <string>();
                // Use a new scope.
                using (var scope = serviceProvider.CreateScope())
                {
                    // Use a new context instance.
                    using var context = scope.ServiceProvider.GetRequiredService <ApplicationDbContext>();
                    // Get the related entities that appear in the current batch.
                    users = context.Users
                            .Where(item => batchUserIds.Contains(item.Id))
                            .ToList();
                    databases = context.Databases
                                .Include(item => item.DatabaseType)
                                .Where(item => batchDatabaseIds.Contains(item.Id))
                                .ToList();
                    nodeCollections = context.NodeCollections
                                      .Include(item => item.NodeCollectionDatabases)
                                      .ThenInclude(item => item.Database)
                                      .Where(item => batchNodeCollectionIds.Contains(item.Id))
                                      .ToList();
                    // Get the valid IDs, that do not appear in the database.
                    validBatchIds = batchIds
                                    .Except(context.Networks
                                            .Where(item => batchIds.Contains(item.Id))
                                            .Select(item => item.Id))
                                    .ToList();
                }
                // Save the items to add.
                var networksToAdd = new List <Network>();
                // Go over each item in the current batch.
                foreach (var batchItem in batchItems)
                {
                    // Check if the ID of the item is not valid.
                    if (!string.IsNullOrEmpty(batchItem.Id) && !validBatchIds.Contains(batchItem.Id))
                    {
                        // Continue.
                        continue;
                    }
                    // Check if there are no network users provided.
                    if (!batchItem.IsPublic && (batchItem.NetworkUsers == null || !batchItem.NetworkUsers.Any()))
                    {
                        // Throw an exception.
                        throw new TaskException("There were no network users provided and the network is not public.", showExceptionItem, batchItem);
                    }
                    // Get the network users.
                    var networkUsers = batchItem.NetworkUsers
                                       .Where(item => item.User != null)
                                       .Where(item => !string.IsNullOrEmpty(item.User.Id))
                                       .Select(item => item.User.Id)
                                       .Distinct()
                                       .Where(item => users.Any(item1 => item1.Id == item))
                                       .Select(item => new NetworkUser
                    {
                        DateTimeCreated = DateTime.UtcNow,
                        UserId          = item
                    });
                    // Check if there were no network users found.
                    if (!batchItem.IsPublic && (networkUsers == null || !networkUsers.Any()))
                    {
                        // Throw an exception.
                        throw new TaskException("There were no network users found and the network is not public.", showExceptionItem, batchItem);
                    }
                    // Check if there are no network databases provided.
                    if (batchItem.NetworkDatabases == null || !batchItem.NetworkDatabases.Any())
                    {
                        // Throw an exception.
                        throw new TaskException("There were no network databases provided.", showExceptionItem, batchItem);
                    }
                    // Get the network databases.
                    var networkDatabases = batchItem.NetworkDatabases
                                           .Where(item => item.Database != null)
                                           .Where(item => !string.IsNullOrEmpty(item.Database.Id))
                                           .Where(item => item.Type == "Node" || item.Type == "Edge")
                                           .Select(item => (item.Database.Id, item.Type))
                                           .Distinct()
                                           .Where(item => databases.Any(item1 => item1.Id == item.Item1))
                                           .Select(item => new NetworkDatabase
                    {
                        DatabaseId = item.Item1,
                        Type       = EnumerationExtensions.GetEnumerationValue <NetworkDatabaseType>(item.Item2)
                    });
                    // Check if there were no network databases found.
                    if (networkDatabases == null || !networkDatabases.Any())
                    {
                        // Throw an exception.
                        throw new TaskException("There were no network databases found.", showExceptionItem, batchItem);
                    }
                    // Check if the network databases have different database types.
                    var batchNetworkDatabaseIds = networkDatabases.Select(item => item.DatabaseId);
                    if (databases.Where(item => batchNetworkDatabaseIds.Contains(item.Id)).Select(item => item.DatabaseType).Distinct().Count() > 1)
                    {
                        // Throw an exception.
                        throw new TaskException("The network databases found have different database types.", showExceptionItem, batchItem);
                    }
                    // Get the node database IDs.
                    var nodeDatabaseIds = networkDatabases
                                          .Where(item => item.Type == NetworkDatabaseType.Node)
                                          .Select(item => item.DatabaseId);
                    // Get the network node collections.
                    var networkNodeCollections = batchItem.NetworkNodeCollections != null?
                                                 batchItem.NetworkNodeCollections
                                                 .Where(item => item.NodeCollection != null)
                                                 .Where(item => !string.IsNullOrEmpty(item.NodeCollection.Id))
                                                 .Where(item => item.Type == "Seed")
                                                 .Select(item => (item.NodeCollection.Id, item.Type))
                                                 .Distinct()
                                                 .Where(item => nodeCollections.Any(item1 => item1.Id == item.Item1 && item1.NodeCollectionDatabases.Any(item2 => nodeDatabaseIds.Contains(item2.Database.Id))))
                                                 .Select(item => new NetworkNodeCollection
                    {
                        NodeCollectionId = item.Item1,
                        Type             = EnumerationExtensions.GetEnumerationValue <NetworkNodeCollectionType>(item.Item2)
                    }) :
                                                     Enumerable.Empty <NetworkNodeCollection>();

                    // Define the new item.
                    var network = new Network
                    {
                        DateTimeCreated        = DateTime.UtcNow,
                        Name                   = batchItem.Name,
                        Description            = batchItem.Description,
                        IsPublic               = batchItem.IsPublic,
                        Status                 = NetworkStatus.Defined,
                        Log                    = JsonSerializer.Serialize(Enumerable.Empty <string>()),
                        Data                   = batchItem.Data,
                        NetworkDatabases       = networkDatabases.ToList(),
                        NetworkUsers           = networkUsers.ToList(),
                        NetworkNodeCollections = networkNodeCollections.ToList()
                    };
                    // Try to get the algorithm.
                    try
                    {
                        // Get the algorithm.
                        network.Algorithm = EnumerationExtensions.GetEnumerationValue <NetworkAlgorithm>(batchItem.Algorithm);
                    }
                    catch (Exception exception)
                    {
                        // Get the exception message.
                        var message = string.IsNullOrEmpty(exception.Message) ? string.Empty : " " + exception.Message;
                        // Throw an exception.
                        throw new TaskException("The algorithm couldn't be determined from the provided string." + message, showExceptionItem, batchItem);
                    }
                    // Append a message to the log.
                    network.Log = network.AppendToLog("The network has been defined and stored in the database.");
                    // Check if there is any ID provided.
                    if (!string.IsNullOrEmpty(batchItem.Id))
                    {
                        // Assign it to the item.
                        network.Id = batchItem.Id;
                    }
                    // Add the new item to the list.
                    networksToAdd.Add(network);
                }
                // Create the items.
                await IEnumerableExtensions.CreateAsync(networksToAdd, serviceProvider, token);

                // Add the IDs of the created items to the list.
                ids = ids.Concat(networksToAdd.Select(item => item.Id));
                // Use a new scope.
                using (var scope = serviceProvider.CreateScope())
                {
                    // Use a new context instance.
                    using var context = scope.ServiceProvider.GetRequiredService <ApplicationDbContext>();
                    // Define the new background task.
                    var backgroundTask = new BackgroundTask
                    {
                        DateTimeCreated = DateTime.UtcNow,
                        Name            = $"{nameof(IContentTaskManager)}.{nameof(IContentTaskManager.GenerateNetworksAsync)}",
                        IsRecurring     = false,
                        Data            = JsonSerializer.Serialize(new NetworksTask
                        {
                            Scheme    = Scheme,
                            HostValue = HostValue,
                            Items     = networksToAdd.Select(item => new NetworkInputModel
                            {
                                Id = item.Id
                            })
                        })
                    };
                    // Mark the task for addition.
                    context.BackgroundTasks.Add(backgroundTask);
                    // Save the changes to the database.
                    await context.SaveChangesAsync();

                    // Create a new Hangfire background job.
                    BackgroundJob.Enqueue <IContentTaskManager>(item => item.GenerateNetworksAsync(backgroundTask.Id, CancellationToken.None));
                }
            }
            // Return the IDs of the created items.
            return(ids);
        }