LinqBuilder 4.1.0
dotnet add package LinqBuilder --version 4.1.0
NuGet\Install-Package LinqBuilder -Version 4.1.0
<PackageReference Include="LinqBuilder" Version="4.1.0" />
<PackageVersion Include="LinqBuilder" Version="4.1.0" />
<PackageReference Include="LinqBuilder" />
paket add LinqBuilder --version 4.1.0
#r "nuget: LinqBuilder, 4.1.0"
#:package LinqBuilder@4.1.0
#addin nuget:?package=LinqBuilder&version=4.1.0
#tool nuget:?package=LinqBuilder&version=4.1.0
LinqBuilder
The specification pattern for LINQ. LinqBuilder lets you write a filter once, as a specification, combine it with other specifications, add ordering and paging, and run it on any IQueryable<T> or IEnumerable<T>. Specifications are expression trees, so Entity Framework Core, Entity Framework 6 and other LINQ providers translate them to SQL.
var spec = new IsAdult()
.And(new LastNameIs("Smith"))
.OrderBy(OrderSpec<Person, string>.New(p => p.FirstName))
.Paginate(pageNo: 1, pageSize: 20);
List<Person> page = await db.People.ExeSpec(spec).ToListAsync();
Full documentation: github.com/Baune8D/LinqBuilder
Features
- Reusable filters: write a specification as a class (
Specification<T>) or inline from a lambda (Spec<T>.New(...)). - Parameters:
DynamicSpecification<T, TValue>passes up to four values into the filter, e.g.new LastNameIs("Smith"). - Composition:
And,OrandNot, plusSpec<T>.All(...),Spec<T>.Any(...)andSpec<T>.None(...). - Ordering and paging:
OrderBy,ThenBy,Skip,TakeandPaginateare stored in the specification and applied byExeSpec. IQueryable<T>andIEnumerable<T>: a query gets the filter as an expression tree, an in-memory collection as a compiled delegate.- LINQ overloads:
Where,Any,All,Count,First,FirstOrDefault,SingleandSingleOrDefaulttake a specification. - In-memory checks:
spec.IsSatisfiedBy(entity). - One specification for several entity types:
MultiSpecification<T1, T2>, up to four types. - Targets .NET Standard 2.0 and .NET 8, 9 and 10.
For async Entity Framework methods that take a specification (AnyAsync, CountAsync, FirstOrDefaultAsync, ...), install LinqBuilder.EFCore or LinqBuilder.EF6 instead. Both depend on this package.
Getting started
1. Install
dotnet add package LinqBuilder
2. Write specifications
The examples use this entity:
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; } = "";
public string LastName { get; set; } = "";
public int Age { get; set; }
public bool IsActive { get; set; }
}
A specification returns its filter from AsExpression():
using System;
using System.Linq.Expressions;
using LinqBuilder;
public class IsAdult : Specification<Person>
{
public override Expression<Func<Person, bool>> AsExpression()
{
return person => person.Age >= 18;
}
}
public class LastNameIs : DynamicSpecification<Person, string>
{
public LastNameIs(string lastName)
: base(lastName)
{
}
public override Expression<Func<Person, bool>> AsExpression()
{
return person => person.LastName == Value;
}
}
For a one-off filter you don't need a class: Spec<Person>.New(p => p.IsActive).
3. Combine and run them
using LinqBuilder;
using LinqBuilder.OrderBy;
ISpecification<Person> spec = new IsAdult()
.And(new LastNameIs("Smith"))
.OrderBy(OrderSpec<Person, string>.New(p => p.FirstName))
.Paginate(pageNo: 2, pageSize: 10);
List<Person> page = people.ExeSpec(spec).ToList(); // filter, sort, skip 10, take 10
int total = people.Count(spec); // filter only: all adults named Smith
people can be any IEnumerable<Person> or IQueryable<Person>, such as a List<Person> or an EF Core DbSet<Person>.
Methods
Creating and combining specifications
Namespace LinqBuilder.
| Method | Description |
|---|---|
Spec<T>.New(expression) |
A specification from a lambda. Spec<T> is an alias of Specification<T>. |
Spec<T>.New() |
An empty specification. It matches every entity and is ignored by And and Or. |
a.And(b), a.Or(b), a.Not() |
Combine filters. The result keeps the ordering, Skip and Take of a. |
Spec<T>.All(a, b, ...) |
Matches entities that match all of them. |
Spec<T>.Any(a, b, ...) |
Matches entities that match at least one of them. |
Spec<T>.None(a, b, ...) |
Same as Spec<T>.Any(a, b, ...).Not(): matches entities that match none of them. |
All, Any and None keep only the filters of their arguments. See Specifications for dynamic (DynamicSpecification) and multi-entity (MultiSpecification) specifications.
Ordering and paging
Namespace LinqBuilder.OrderBy.
| Method | Description |
|---|---|
OrderSpec<T, TResult>.New(keySelector, sort) |
An order specification (one sort key). sort is Sort.Ascending (the default) or Sort.Descending. OrderSpec is an alias of OrderSpecification. |
spec.OrderBy(order) |
Adds order as a sort key. Returns an IOrderedSpecification<T>. |
ordered.ThenBy(order) |
Adds another sort key, on the result of OrderBy or ThenBy, or on an order specification. |
spec.UseOrdering(other) |
A copy of spec with the sort keys of other added. Skip and Take come from other when it sets them, otherwise from spec. |
spec.Skip(count), spec.Take(count) |
Set the number of entities to skip and the maximum number to return. Calling them again replaces the value. |
spec.Paginate(pageNo, pageSize) |
Skip((pageNo - 1) * pageSize) and Take(pageSize). pageNo starts at 1. |
spec.IsOrdered(), spec.HasSkip(), spec.HasTake() |
Check whether a specification has sort keys, a Skip or a Take. |
Running specifications
Namespace LinqBuilder.
| Method | Description |
|---|---|
source.ExeSpec(spec) |
Applies the filter, sort keys, Skip and Take, in that order. Returns an IQueryable<T> for a query and an IEnumerable<T> for a collection. |
source.ExeSpec(spec, skipSort: true) |
Applies only the filter. |
Where, Any, All, Count, First, FirstOrDefault, Single, SingleOrDefault |
LINQ overloads that take a specification, on IQueryable<T> and IEnumerable<T>. They use only the filter and ignore the sort keys, Skip and Take. |
spec.IsSatisfiedBy(entity) |
Runs the filter on one entity. |
spec.Clone() |
A new specification with the same filter, sort keys, Skip and Take. |
License
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- LinqKit.Core (>= 1.3.1)
-
net10.0
- LinqKit.Core (>= 1.3.1)
-
net8.0
- LinqKit.Core (>= 1.3.1)
-
net9.0
- LinqKit.Core (>= 1.3.1)
NuGet packages (4)
Showing the top 4 NuGet packages that depend on LinqBuilder:
| Package | Downloads |
|---|---|
|
LinqBuilder.EFCore
Entity Framework Core extensions. Enables most async methods to use ISpecification. |
|
|
LinqBuilder.EF6
Entity Framework 6 extensions. Enables most async methods to use ISpecification. |
|
|
LinqBuilder.EF6.AutoMapper
Extensions for querying EF 6 with AutoMapper projections. |
|
|
LinqBuilder.EFCore.AutoMapper
Extensions for querying EF Core with AutoMapper projections. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.1.0 | 0 | 11/2/2026 |
| 4.0.0 | 1,672 | 1/8/2026 |
| 3.2.0 | 13,827 | 12/30/2024 |
| 3.1.0 | 14,489 | 5/5/2024 |
| 3.0.1 | 18,083 | 10/18/2023 |
| 3.0.0 | 363 | 10/17/2023 |
| 2.1.2 | 44,837 | 4/14/2022 |
| 2.1.1 | 1,107 | 4/13/2022 |
| 2.1.0 | 1,096 | 4/13/2022 |
| 2.0.0 | 1,856 | 1/19/2021 |
| 1.0.1 | 8,913 | 11/3/2020 |
| 1.0.0 | 1,119 | 11/3/2020 |
| 0.16.1 | 54,268 | 8/29/2019 |
| 0.15.0 | 4,822 | 12/4/2018 |
| 0.14.0 | 1,028 | 12/3/2018 |
| 0.13.0 | 4,752 | 9/17/2018 |
| 0.12.1 | 1,797 | 7/18/2018 |
| 0.12.0 | 1,283 | 7/18/2018 |
| 0.11.1 | 1,286 | 7/18/2018 |
| 0.11.0 | 1,791 | 6/24/2018 |