Skip to content

Best Practices

Error Handling and Edge Cases

When working with specifications, consider these common scenarios:

Null Safety

csharp
public static class ProductSpecification
{
    // Handle null strings safely
    public static Specification<Product> HasCategory(string categoryName) =>
        Specification.Create<Product>(p =>
            p.Category != null && p.Category.Equals(categoryName, StringComparison.OrdinalIgnoreCase));

    // Handle null navigation properties
    public static Specification<Product> HasSupplier =>
        Specification.Create<Product>(p => p.Supplier != null);

    // Combine for safe navigation
    public static Specification<Product> FromSupplierInCountry(string country) =>
        HasSupplier.And(Specification.Create<Product>(
            p => p.Supplier!.Country.Equals(country, StringComparison.OrdinalIgnoreCase)));
}

Database Translation Limitations

Some C# expressions cannot be translated to SQL. Keep specifications simple and database-friendly:

csharp
// Using complex string methods that may not translate to SQL
public static Specification<Product> HasComplexNamePattern { get; } =
    Specification.Create<Product>(p =>
        p.Name.Split(',').Any(part => part.Trim().StartsWith("Pro")));
csharp
// Using simple, translatable operations
public static Specification<Product> NameStartsWithPro { get; } =
    Specification.Create<Product>(p => p.Name.StartsWith("Pro"));

public static Specification<Product> NameContainsPro { get; } =
    Specification.Create<Product>(p => p.Name.Contains("Pro"));

Released under the MIT License.