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");
}
}