Superfilter 1.0.1

dotnet add package Superfilter --version 1.0.1
                    
NuGet\Install-Package Superfilter -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Superfilter" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Superfilter" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Superfilter" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Superfilter --version 1.0.1
                    
#r "nuget: Superfilter, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Superfilter@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Superfilter&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Superfilter&version=1.0.1
                    
Install as a Cake Tool

stable NuGet GitHub

Superfilter

Superfilter is a lightweight C# library for applying dynamic filtering and sorting on IQueryable sources. It maps textual filter criteria to strongly typed expressions, making it easy to expose flexible query capabilities in web APIs or other data-driven applications.

🎯 Framework Support: .NET 8.0 and .NET 9.0

Features

  • πŸš€ Fluent IQueryable Extensions - Natural integration with LINQ queries
  • πŸ“„ Pagination Support - Built-in pagination with IHasPagination interface
  • Map filter keys to entity properties with lambda selectors and type inference
  • Supports nested navigation properties (e.g., x => x.Car.Brand.Name)
  • Validates required filters with configurable error handling
  • Built‑in operators: Equals, LessThan, GreaterThan, StartsWith, Contains, IsEqualToYear, IsEqualToYearAndMonth, IsEqualToFullDate
  • Integrated sorting functionality
  • Works seamlessly with Entity Framework and LINQ-to-Objects
  • Type-safe expression building with proper type inference
  • IntelliSense support with compile-time type checking

Getting Started

πŸš€ Fluent IQueryable Extensions

using Superfilter;

// In a controller or service method
[HttpPost("search")]
public async Task<IActionResult> SearchUsers([FromBody] UserSearchRequest request)
{
    // Apply filters using fluent IQueryable extensions
    var result = await _context.Users
        .WithSuperfilter()                               // Start fluent configuration
        .MapProperty(u => u.Id)                          // IntelliSense support
        .MapProperty(u => u.Car.Brand.Name)              // Navigation properties work naturally
        .MapProperty("name", u => u.Name)                // Explicit key usage
        .MapRequiredProperty(u => u.MoneyAmount)         // Require this property to be included in filters
        .WithFilters(request.Filters)                    // Apply dynamic filters - returns filtered IQueryable
        .ToListAsync();
    
    return Ok(result);
}

With Sorting

// Apply both filters and sorting
var result = await _context.Users
    .WithSuperfilter()
    .MapProperty(u => u.Name)
    .MapProperty(u => u.Age)
    .MapProperty(u => u.MoneyAmount)
    .WithFilters(request.Filters)                        // Apply filters
    .ApplySorting(request.Sorts)                         // Apply sorting
    .ToListAsync();

With Pagination

// Using IHasPagination interface for pagination support
public class UserSearchRequest : IHasPagination, IHasFilters
{
    public int PageNumber { get; set; } = 1;
    public int PageSize { get; set; } = 10;
    public List<FilterCriterion> Filters { get; set; } = new();
}

// Apply filters with pagination
[HttpPost("search")]
public async Task<IActionResult> SearchUsers([FromBody] UserSearchRequest request)
{
    var query = _context.Users
        .WithSuperfilter()
        .MapProperty(u => u.Name)
        .MapProperty(u => u.Age)
        .WithFilters(request.Filters);

    // Apply pagination using Skip and Take
    var skip = (request.PageNumber - 1) * request.PageSize;
    var result = await query
        .Skip(skip)
        .Take(request.PageSize)
        .ToListAsync();
    
    return Ok(result);
}

API Reference

Core Extension Methods

Method Description
.WithSuperfilter() Starts fluent configuration chain for IQueryable
MapProperty<TProperty>(selector) Maps property with auto-generated key
MapProperty<TProperty>(key, selector) Maps property with explicit key
MapRequiredProperty<TProperty>(selector) Maps required property with auto-generated key
MapRequiredProperty<TProperty>(key, selector) Maps required property with explicit key
WithFilters(IHasFilters) Applies filters and returns filtered IQueryable
AddStaticFilter(field, operator, value) Adds a static filter
WithErrorStrategy(OnErrorStrategy) Sets error handling strategy

Property Mapping Examples

// MapProperty handles all types automatically with type inference
var result = _context.Users
    .WithSuperfilter()
    .MapProperty(u => u.Name)                    // string - auto key: "User.Name"
    .MapProperty(u => u.Id)                      // int - auto key: "User.Id"
    .MapProperty(u => u.BornDate)                // DateTime? - auto key: "User.BornDate"
    .MapProperty(u => u.MoneyAmount)             // int - auto key: "User.MoneyAmount"
    .MapProperty(u => u.IsActive)                // bool - auto key: "User.IsActive"
    .MapProperty(u => u.Car.Brand.Name)          // nested string - auto key: "User.Car.Brand.Name"
    .MapProperty("customKey", u => u.Email)      // explicit key
    .WithFilters(request.Filters)
    .ToList();

Error Handling

// Configure error handling strategy
var result = _context.Users
    .WithSuperfilter()
    .WithErrorStrategy(OnErrorStrategy.Ignore)   // Or OnErrorStrategy.ThrowException
    .MapProperty(u => u.Name)
    .WithFilters(request.Filters)
    .ToList();

Static Filters

// Add static filters (applied in addition to dynamic filters)
var result = _context.Users
    .WithSuperfilter()
    .MapProperty(u => u.Name)
    .MapProperty(u => u.IsActive)
    .AddStaticFilter("User.IsActive", Operator.Equals, "true")  // Always filter active users
    .WithFilters(request.Filters)                               // Plus dynamic filters from client
    .ToList();

Supported Operators

Operator Description Example
Equals Exact match name = "John"
Contains String contains name LIKE "%John%"
StartsWith String starts with name LIKE "John%"
LessThan Numeric/Date less than age < 30
GreaterThan Numeric/Date greater than age > 18
IsEqualToYear Date year equals YEAR(birthDate) = 1990
IsEqualToYearAndMonth Date year and month equals YEAR(birthDate) = 1990 AND MONTH(birthDate) = 5
IsEqualToFullDate Full date equals DATE(birthDate) = '1990-05-15'

Note on Property Mapping

The MapProperty method is available in two forms:

  1. MapProperty(key, selector) - Explicit key definition for the property mapping
  2. MapProperty(selector) - Auto-generated key based on property path

Security Note: When using auto-generated keys (MapProperty(selector)), consider whether exposing your data model schema to the frontend is acceptable for your use case. This approach might reveal internal details of your data model structure.

Benchmarks show better results with Superfilter

<img width="1006" height="251" alt="image" src="https://github.com/user-attachments/assets/0dc5d072-72f1-4734-b32c-c132ffab9c02" />

Installation

dotnet add package Superfilter --version 1.0.1

Project Structure

Superfilter/
β”œβ”€β”€ SuperFilter/           # Core library implementation
β”‚   β”œβ”€β”€ Extensions/        # IQueryable extensions
β”‚   β”œβ”€β”€ Constants/         # Operator definitions
β”‚   └── ExpressionBuilders/# Type-specific expression builders
β”œβ”€β”€ Database/              # EF Core context and domain models
└── Tests/                 # Comprehensive test suite

Running Tests

# Run all tests
dotnet test

# Run tests with detailed output
dotnet test --verbosity normal

# Exclude PostgreSQL integration tests (require Docker)
dotnet test --filter "FullyQualifiedName!~PostgreSqlIntegrationTests"

Key Benefits

  • βœ… Fluent Integration with existing IQueryable workflows
  • βœ… Type Safety with compile-time checking and IntelliSense support
  • βœ… Zero Configuration - works out of the box with sensible defaults
  • βœ… Natural Navigation Properties support without complex setup
  • βœ… Flexible Filtering - combine static and dynamic filters seamlessly
  • βœ… Entity Framework Ready - optimized for EF Core query generation

License

This project is licensed under the MIT License.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.
  • net9.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 91 7/28/2025
1.0.0 91 7/28/2025
0.2.0 366 7/21/2025
0.1.6-alpha 116 7/15/2025
0.1.5-alpha 116 7/15/2025
0.1.4-alpha 116 7/14/2025
0.1.3-alpha 116 7/13/2025
0.1.2-alpha 112 7/13/2025
0.1.1-alpha 114 7/13/2025
0.1.0-alpha 115 7/13/2025

Version 1.0.1: Added pagination support with IHasPagination interface. Enhanced filtering capabilities with pagination integration.