Bulk Validation

Validate collections and objects in bulk with detailed reporting and performance optimization.

What is Bulk Validation?

Bulk Validation in Validixty allows you to validate large collections of objects efficiently. It provides parallel processing capabilities, detailed reporting, and performance monitoring for high-throughput validation scenarios.

Why Use Bulk Validation?

  • Performance: Parallel processing for large datasets
  • Efficiency: Batch validation operations
  • Reporting: Comprehensive validation statistics
  • Scalability: Handle thousands of items efficiently

Before Using Validixty

Without bulk validation, processing large collections might look like this:

public BulkValidationResult ValidateUsers(List users)
{
    var results = new List();
    var validCount = 0;
    var invalidCount = 0;
    var errors = new Dictionary>();

    foreach (var user in users)
    {
        var userErrors = new List();

        // Validate each field individually
        if (string.IsNullOrEmpty(user.Email) ||
            !Regex.IsMatch(user.Email, "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"))
        {
            userErrors.Add("Invalid email");
        }

        if (string.IsNullOrEmpty(user.Phone) ||
            !Regex.IsMatch(user.Phone, "^(\\+20|0)?1[0-2,5]\\d{8}$"))
        {
            userErrors.Add("Invalid phone");
        }

        if (string.IsNullOrEmpty(user.Name) || user.Name.Length < 2)
        {
            userErrors.Add("Invalid name");
        }

        if (userErrors.Any())
        {
            invalidCount++;
            errors[user.Email] = userErrors;
        }
        else
        {
            validCount++;
        }
    }

    return new BulkValidationResult
    {
        TotalCount = users.Count,
        ValidCount = validCount,
        InvalidCount = invalidCount,
        Errors = errors
    };
}

After Using Validixty

With Validixty's Bulk Validation, the same operation becomes simple and efficient:

using Validixty.Core;

var users = GetUsersFromDatabase();
var result = BulkValidation.ValidateCollection(users, user => {
    // Custom validation logic for each user
    var validation = Validation.For($"User-{user.Id}")
        .CheckEmail(user.Email)
        .CheckPhone(x => x.Country == CountriesEnum.Egypt, user.Phone)
        .Check(x => !string.IsNullOrEmpty(x.Name) && x.Name.Length >= 2, "Name is required and must be at least 2 characters")
        .Validate();

    return new ValidationResult($"User-{user.Id}", user.Email, validation.IsValid, validation.ErrorMessage);
});

// Access results
Console.WriteLine($"Total: {result.TotalCount}, Valid: {result.ValidCount}, Invalid: {result.InvalidCount}");

How It Saves Time

  • Eliminates loops: Single API call for entire collections
  • Parallel processing: Automatic performance optimization
  • Detailed reporting: Built-in statistics and error tracking
  • Memory efficient: Streaming validation for large datasets

Usage Examples

Simple Collection Validation

var emails = new[] { "user1@domain.com", "user2@domain.com", "invalid-email" };
var emailResults = BulkValidation.ValidateCollection(emails, email =>
    new ValidationResult("Email", email, Validation.Communication.EmailAddress.IsValid(email), "Invalid email format"));

Console.WriteLine($"Valid emails: {emailResults.ValidCount}/{emailResults.TotalCount}");

Complex Object Validation

class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
    public string Sku { get; set; }
}

var products = GetProductsFromDatabase();
var productResults = BulkValidation.ValidateCollection(products, product =>
{
    var validation = Validation.For($"Product-{product.Sku}")
        .Check(x => !string.IsNullOrEmpty(x.Name), "Name is required")
        .Check(x => x.Price > 0, "Price must be greater than zero")
        .Check(x => !string.IsNullOrEmpty(x.Sku) && x.Sku.Length >= 3, "SKU is required and must be at least 3 characters")
        .Validate();

    return new ValidationResult($"Product-{product.Sku}", product.Name, validation.IsValid, validation.ErrorMessage);
});

Async Bulk Validation

// For large datasets or I/O bound operations
var largeDataset = await GetLargeDatasetAsync();
var asyncResults = await BulkValidation.ValidateCollectionAsync(largeDataset, async item =>
{
    // Simulate async validation (e.g., database lookup)
    await Task.Delay(10); // Simulate I/O

    var validation = Validation.For($"Item-{item.Id}")
        .CheckEmail(item.Email)
        .Validate();

    return new ValidationResult($"Item-{item.Id}", item.Email, validation.IsValid, validation.ErrorMessage);
});

Validation Statistics and Reporting

var bulkResult = BulkValidation.ValidateCollection(items, item => /* validation logic */);

// Get detailed statistics
var stats = bulkResult.GetStatistics();
Console.WriteLine($"Validation completed in: {stats.Duration.TotalMilliseconds}ms");
Console.WriteLine($"Average validation time per item: {stats.AverageTimePerItem.TotalMilliseconds}ms");
Console.WriteLine($"Peak memory usage: {stats.PeakMemoryUsage} bytes");

// Get error summary
var errorSummary = bulkResult.GetErrorSummary();
foreach (var errorGroup in errorSummary)
{
    Console.WriteLine($"Error '{errorGroup.ErrorMessage}': {errorGroup.Count} occurrences");
}

Parallel Processing Configuration

// Configure parallel processing for optimal performance
var options = new BulkValidationOptions
{
    MaxDegreeOfParallelism = Environment.ProcessorCount, // Use all cores
    BatchSize = 1000, // Process in batches of 1000
    EnableStatistics = true,
    CancellationToken = cancellationToken
};

var parallelResults = await BulkValidation.ValidateCollectionAsync(
    largeCollection,
    item => ValidateItem(item),
    options);

Error Handling and Recovery

try
{
    var results = BulkValidation.ValidateCollection(items, item =>
    {
        try
        {
            return ValidateItem(item);
        }
        catch (Exception ex)
        {
            // Log error and continue processing
            _logger.LogError(ex, $"Validation failed for item {item.Id}");
            return new ValidationResult($"Item-{item.Id}", item.Name, false, "Validation error occurred");
        }
    });

    // Process results even if some validations failed
    ProcessValidItems(results.ValidItems);
    HandleInvalidItems(results.InvalidItems);
}
catch (AggregateException ex)
{
    // Handle multiple validation exceptions
    foreach (var innerEx in ex.InnerExceptions)
    {
        _logger.LogError(innerEx, "Bulk validation error");
    }
}