Cirreum.ExpressionBuilder 1.0.104

dotnet add package Cirreum.ExpressionBuilder --version 1.0.104
                    
NuGet\Install-Package Cirreum.ExpressionBuilder -Version 1.0.104
                    
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="Cirreum.ExpressionBuilder" Version="1.0.104" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Cirreum.ExpressionBuilder" Version="1.0.104" />
                    
Directory.Packages.props
<PackageReference Include="Cirreum.ExpressionBuilder" />
                    
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 Cirreum.ExpressionBuilder --version 1.0.104
                    
#r "nuget: Cirreum.ExpressionBuilder, 1.0.104"
                    
#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 Cirreum.ExpressionBuilder@1.0.104
                    
#: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=Cirreum.ExpressionBuilder&version=1.0.104
                    
Install as a Cake Addin
#tool nuget:?package=Cirreum.ExpressionBuilder&version=1.0.104
                    
Install as a Cake Tool

Cirreum.ExpressionBuilder

NuGet Version NuGet Downloads GitHub Release

A powerful, fluent C# library for dynamically building LINQ expressions and lambda functions. Build complex queries programmatically with compile-time safety and runtime flexibility.

Features

  • Fluent API: Intuitive, chainable syntax for building complex filters
  • Type Safety: Compile-time checking with generic type constraints
  • Dynamic Querying: Build expressions from user input, configuration, or runtime conditions
  • Null Safety: Automatic null-checking prevents runtime exceptions
  • Collection Support: Query nested collections and complex object graphs
  • Extensible: Create custom operators for domain-specific filtering
  • Database Ready: Works seamlessly with Entity Framework and other ORMs
  • Client-Side Ready: Perfect for Blazor and other client-side scenarios where dynamic filtering needs to be built from user input

Quick Start

Installation

dotnet add package Cirreum.ExpressionBuilder

Basic Usage

using Cirreum.ExpressionBuilder;

// Simple property filtering
var filter = new Filter<Person>();
filter.By("Age", Operators.GreaterThan, 18)
      .And.By("Name", Operators.Contains, "John");

var adults = people.Where(filter).ToList();

Complex Queries

// Grouped conditions with nested properties
var filter = new Filter<Person>();
filter.By("Age", Operators.Between, 18, 65)
      .And.Group
          .By("Department.Name", Operators.EqualTo, "Engineering")
          .Or.By("Department.Name", Operators.EqualTo, "Product")
      .And.By("Contacts[Type]", Operators.EqualTo, ContactType.Email);

var results = employees.Where(filter).ToList();

Property Conventions

The library uses a simple convention for referencing properties:

Pattern Example Description
PropertyName "Age" Direct property access
Parent.Property "Department.Name" Nested object properties
Collection[Property] "Contacts[Email]" Properties of collection items

Supported Operations

Text Operations

  • Contains, DoesNotContain
  • StartsWith, EndsWith
  • EqualTo, NotEqualTo
  • IsEmpty, IsNotEmpty
  • IsNull, IsNotNull
  • IsNullOrWhiteSpace, IsNotNullNorWhiteSpace

Numeric/Date Operations

  • EqualTo, NotEqualTo
  • GreaterThan, GreaterThanOrEqualTo
  • LessThan, LessThanOrEqualTo
  • Between

Collection Operations

  • In, NotIn (check if value exists in a list)

Boolean Operations

  • EqualTo, NotEqualTo

Advanced Examples

Dynamic Filtering from User Input

public IQueryable<Product> FilterProducts(IQueryable<Product> products, 
                                        FilterRequest request)
{
    var filter = new Filter<Product>();
    
    if (!string.IsNullOrEmpty(request.Category))
        filter.By("Category", Operators.EqualTo, request.Category);
    
    if (request.MinPrice.HasValue)
        filter.And.By("Price", Operators.GreaterThanOrEqualTo, request.MinPrice.Value);
    
    if (request.MaxPrice.HasValue)
        filter.And.By("Price", Operators.LessThanOrEqualTo, request.MaxPrice.Value);
    
    return products.Where(filter);
}

Grouping Conditions

var filter = new Filter<Employee>();

// (Department = 'IT' OR Department = 'Engineering') 
// AND (Status = 'Active' AND HireDate > '2020-01-01')
filter.By("Department", Operators.EqualTo, "IT")
      .Or.By("Department", Operators.EqualTo, "Engineering")
      .And.Group
          .By("Status", Operators.EqualTo, "Active")
          .And.By("HireDate", Operators.GreaterThan, new DateTime(2020, 1, 1));

var results = employees.Where(filter).ToList();

Custom Operators

Create domain-specific operators for specialized filtering:

public class IsWithinRadius : OperatorBase
{
    public IsWithinRadius() : base("IsWithinRadius", 2, TypeGroup.Number) { }
    
    public override Expression GetExpression(MemberExpression member, 
                                           ConstantExpression lat, 
                                           ConstantExpression lng)
    {
        // Implement distance calculation logic
        // Return expression for: distance <= radius
    }
}

// Register custom operator
Operators.LoadOperators(new List<IOperator> { new IsWithinRadius() });

Entity Framework Integration

Works seamlessly with EF Core for database queries:

public async Task<List<Customer>> GetFilteredCustomersAsync(CustomerFilter filterRequest)
{
    var filter = new Filter<Customer>();
    
    if (!string.IsNullOrEmpty(filterRequest.City))
        filter.By("Address.City", Operators.EqualTo, filterRequest.City);
    
    if (filterRequest.HasActiveOrders)
        filter.And.By("Orders[Status]", Operators.EqualTo, OrderStatus.Active);
    
    return await context.Customers
        .Where(filter)
        .ToListAsync();
}

Performance Considerations

  • Expressions are compiled once and can be reused
  • Use IQueryable interfaces for database queries to ensure server-side execution
  • Complex nested queries may benefit from database indexes on filtered properties

Error Handling

The library provides detailed exceptions for common issues:

  • UnsupportedOperationException: Operation not supported for the property type
  • PropertyValueTypeMismatchException: Type mismatch between property and filter value
  • WrongNumberOfValuesException: Incirreumect number of values for an operation

Thread Safety

Filter<T> instances are not thread-safe. Create separate instances for concurrent operations or use appropriate synchronization.

Acknowledgments

This library builds upon the excellent foundation provided by David Belmont's ExpressionBuilder. We've extended and modernized the codebase while maintaining the core philosophy of simple, powerful expression building.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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.
  • net10.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Cirreum.ExpressionBuilder:

Package Downloads
Cirreum.Components.WebAssembly

The Cirreum Component Library for WebAssembly.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.104 284 1/21/2026
1.0.103 599 12/20/2025
1.0.102 675 11/11/2025
1.0.101 296 11/11/2025
1.0.100 199 11/6/2025