private async Task CreateNewItemsAsync()

in src/Epam.GraphQL/Loaders/MutableLoader.cs [440:531]


        private async Task CreateNewItemsAsync(IResolveFieldContext context, IProfiler profiler, IDataContext dbContext, IEnumerable<SaveResultItem<TEntity, TId>> itemsToCreate)
        {
            var graphqlContext = (GraphQLContext<TExecutionContext>?)context.UserContext["ctx"];
            Guards.AssertIfNull(graphqlContext);

            if (itemsToCreate.Any())
            {
                using (profiler.Step($"Create"))
                {
                    using (profiler.Step($"CanCreate"))
                    {
                        var canCreateTasks = itemsToCreate.Select(item => CanSaveAsync(graphqlContext, item.Payload, true));

                        var canCreate = true;
                        foreach (var canCreateTask in canCreateTasks)
                        {
                            if (!await canCreateTask.ConfigureAwait(false))
                            {
                                canCreate = false;
                                break;
                            }
                        }

                        if (!canCreate)
                        {
                            throw new ExecutionError($"Cannot create entity (type: {typeof(TEntity).HumanizedName()}): Unauthorized.");
                        }
                    }

                    var payloadOnly = itemsToCreate.Select(r => r.Payload);

                    foreach (var item in itemsToCreate)
                    {
                        foreach (var field in InputObjectGraphTypeConfigurator.Fields
                            .Where(f => f.EditSettings != null && f.EditSettings.GetDefaultValue != null)
                            .OfType<IExpressionFieldConfiguration<TEntity, TExecutionContext>>()
                            .Where(f => f.PropertyInfo != null))
                        {
                            var defaultValue = field.EditSettings!.GetDefaultValue!(context, item.Payload);
                            item.Payload.SetPropertyValue(field.PropertyInfo!, defaultValue);
                        }
                    }

                    using (profiler.Step($"BeforeCreate"))
                    {
                        foreach (var item in payloadOnly)
                        {
                            await BeforeCreateAsync(context.GetUserContext<TExecutionContext>(), item).ConfigureAwait(false);
                        }
                    }

                    using (profiler.Step($"Checks"))
                    {
                        var errors = itemsToCreate.SelectMany(item =>
                        {
                            var fieldTypes = item.Properties.Keys
                                .Select(propName => InputObjectGraphTypeConfigurator.FindFieldByName(propName))
                                .OfType<IExpressionFieldConfiguration<TEntity, TExecutionContext>>()
                                .Where(field => field.PropertyInfo != null)
                                .Select(field => field.PropertyInfo!.PropertyType)
                                .Where(propertyType => propertyType.IsValueType && !TypeExtensions.IsNullable(propertyType))
                                .ToList();

                            var fields = InputObjectGraphTypeConfigurator.Fields
                                .OfType<IExpressionFieldConfiguration<TEntity, TExecutionContext>>()
                                .Where(field => field.PropertyInfo != null && field.PropertyInfo.PropertyType.IsValueType && !TypeExtensions.IsNullable(field.PropertyInfo.PropertyType)
                                    && fieldTypes.All(fieldType => fieldType != field.PropertyInfo.PropertyType))
                                .Where(field => field.EditSettings?.GetDefaultValue == null);

                            return fields
                                .Select(field => $"Cannot create entity: Field `{field.Name}` cannot be null (type: {typeof(TEntity).HumanizedName()}, id: {GetId(item.Payload)}).");
                        });

                        if (errors.Any())
                        {
                            throw new ExecutionError(string.Join("\n\r", errors));
                        }
                    }

                    using (profiler.Step($"CustomSave"))
                    {
                        foreach (var item in itemsToCreate)
                        {
                            IdSetter(item.Payload, default!);
                            await CustomSave(context, item, item.Payload).ConfigureAwait(false);
                        }
                    }

                    dbContext.AddRange(payloadOnly);
                }
            }
        }