{"id":13735487,"url":"https://github.com/tghamm/dynamic-linq-query-builder","last_synced_at":"2026-01-27T04:00:38.779Z","repository":{"id":37085180,"uuid":"47482714","full_name":"tghamm/dynamic-linq-query-builder","owner":"tghamm","description":"A truly generic and dynamic linq query builder to compliment jQuery QueryBuilder and other dynamic linq query generation needs","archived":false,"fork":false,"pushed_at":"2024-10-09T01:17:42.000Z","size":2108,"stargazers_count":267,"open_issues_count":14,"forks_count":111,"subscribers_count":16,"default_branch":"master","last_synced_at":"2026-01-16T18:03:25.723Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tghamm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-12-06T03:50:59.000Z","updated_at":"2025-08-01T08:24:57.000Z","dependencies_parsed_at":"2024-01-07T17:14:02.708Z","dependency_job_id":"7cf3dcf7-2445-4b2c-920a-eaa6bd24c315","html_url":"https://github.com/tghamm/dynamic-linq-query-builder","commit_stats":{"total_commits":125,"total_committers":23,"mean_commits":5.434782608695652,"dds":0.352,"last_synced_commit":"921199df7e2421b1a392977beeaff36a11daa78c"},"previous_names":["castle-it/dynamic-linq-query-builder"],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/tghamm/dynamic-linq-query-builder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tghamm%2Fdynamic-linq-query-builder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tghamm%2Fdynamic-linq-query-builder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tghamm%2Fdynamic-linq-query-builder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tghamm%2Fdynamic-linq-query-builder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tghamm","download_url":"https://codeload.github.com/tghamm/dynamic-linq-query-builder/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tghamm%2Fdynamic-linq-query-builder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28800877,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T03:44:14.111Z","status":"ssl_error","status_checked_at":"2026-01-27T03:43:33.507Z","response_time":168,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T03:01:07.367Z","updated_at":"2026-01-27T04:00:38.763Z","avatar_url":"https://github.com/tghamm.png","language":"C#","funding_links":[],"categories":["Libraries","C\\#"],"sub_categories":["Reflection and Expression"],"readme":"# Dynamic Linq Query Builder\n[![.NET](https://github.com/tghamm/dynamic-linq-query-builder/actions/workflows/dotnet.yml/badge.svg)](https://github.com/tghamm/dynamic-linq-query-builder/actions/workflows/dotnet.yml) [![Coverage Status](https://coveralls.io/repos/github/tghamm/dynamic-linq-query-builder/badge.svg?branch=master)](https://coveralls.io/github/tghamm/dynamic-linq-query-builder?branch=master) [![Nuget](https://img.shields.io/nuget/dt/Castle.DynamicLinqQueryBuilder)](https://www.nuget.org/packages/Castle.DynamicLinqQueryBuilder/)\n\n`dynamic-linq-query-builder` is a small library that allows any .NET collection to be filtered dynamically at runtime.\n\n## What's New in v2.0\n\nVersion 2.0 is a performance-focused release that targets **.NET 8+** exclusively. By dropping support for legacy frameworks (.NET 4.5, .NET Standard 2.0, .NET 6), we were able to leverage modern .NET APIs that simply weren't available before:\n\n- **`FrozenDictionary`** for faster operator dispatch\n- **Native `System.DateOnly`** instead of a custom workaround\n- **Modern caching primitives** for expression and reflection caching\n\nThe result is a faster, leaner library with new opt-in features for scenarios where performance really matters.\n\n\u003e **Still on an older framework?** Version 1.3.4 remains available on NuGet and continues to support .NET 4.5, .NET Standard 2.0, .NET 6, and .NET 8.\n\n## Features\n\n- Generates an `IQueryable` from any collection and filter combination\n- Capable of complex, grouped queries against as many fields as you want\n- Supports nested objects and collections via dot notation\n- Supports ORMs like `EF6`, `EF Core`, and `MongoDB Client \u003e=2.19`\n- Compatible with [jQuery QueryBuilder](https://querybuilder.js.org) (see samples for an example)\n- Supports a number of operators for each type:\n  - in\n  - not in\n  - equal\n  - not equal\n  - between\n  - not between\n  - less\n  - less or equal\n  - greater\n  - greater or equal\n  - begins with\n  - not begins with\n  - contains\n  - not contains\n  - ends with\n  - not ends with\n  - is empty\n  - is not empty\n  - is null\n  - is not null\n  - custom operators via `IFilterOperator` interface and options\n\n### New in v2.0\n\n- **Expression \u0026 predicate caching** — opt-in caching for repeated queries (up to 150x faster)\n- **Optimized string comparison** — opt-in `StringComparison.OrdinalIgnoreCase` mode for in-memory scenarios\n- **HashSet optimization** — automatic O(1) lookups for large `in` operations\n- **Reduced allocations** — internal caching of reflection lookups and static lambdas\n\n## Performance at a Glance\n\n| Scenario | v1.3.4 | v2.0 | Improvement |\n|----------|-------:|-----:|-------------|\n| Large `in` (500 values) | 3,525 μs | 421 μs | **88% faster** |\n| Repeated queries (cached) | 210 μs | 1.4 μs | **150x faster** |\n| String filter (ordinal mode) | 490 μs | 309 μs | **37% faster**, 85% less memory |\n\n\n## Quick Start: New v2.0 Options\n\nAll new features are **opt-in** — your existing code works without changes.\n\n### Expression Caching\n\nIf you're running the same filter structure repeatedly (e.g., in a loop or API endpoint), enable caching to skip redundant expression building:\n\n```csharp\nvar options = new BuildExpressionOptions \n{ \n    EnableExpressionCaching = true,  // Cache built expression trees\n    EnablePredicateCaching = true    // Cache compiled delegates\n};\n\n// First call builds and caches; subsequent calls are ~150x faster\nvar results = myCollection.BuildQuery(filter, options).ToList();\n```\n\n### Optimized String Comparison\n\nFor **in-memory** scenarios (not EF Core or other ORMs), enable ordinal string comparison to avoid `ToLower()` allocations:\n\n```csharp\nvar options = new BuildExpressionOptions \n{ \n    UseOrdinalStringComparison = true  // Uses StringComparison.OrdinalIgnoreCase\n};\n\nvar results = myCollection.BuildQuery(filter, options).ToList();\n```\n\n\u003e **Note:** Keep this `false` (default) when using with EF Core, EF6, or other ORMs that translate expressions to SQL. The `ToLower()` approach is required for database compatibility.\n\n## Installation\n\nInstall via NuGet UI or Package Manager Console:\n\n```\nPM\u003e Install-Package Castle.DynamicLinqQueryBuilder\n```\n\nFor System.Text.Json support:\n\n```\nPM\u003e Install-Package Castle.DynamicLinqQueryBuilder.SystemTextJson\n```\n\n**Targets:** .NET 8+\n\n## Upgrading from v1.x\n\nMigrating to v2.0 is straightforward:\n\n1. **Update your target framework** to `net8.0` or later\n2. **Update the NuGet package** to v2.0\n3. **That's it!** All new options are opt-in; existing code works unchanged\n\nIf you can't upgrade to .NET 8, stay on v1.3.4 — it's still fully functional and available on NuGet.\n\n## Getting Started\n\nThe easiest way to get started is to install the NuGet package and take a look at the MVC sample application included in the source code. It contains a working example of both `dynamic-linq-query-builder` and `jQuery-QueryBuilder`.\n\nFor more details, see the [Wiki](https://github.com/tghamm/dynamic-linq-query-builder/wiki).\n\n## Contributions\n\nContributions and pull requests are welcome with associated unit tests.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftghamm%2Fdynamic-linq-query-builder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftghamm%2Fdynamic-linq-query-builder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftghamm%2Fdynamic-linq-query-builder/lists"}