NPredicateBuilder 5.3.0
dotnet add package NPredicateBuilder --version 5.3.0
NuGet\Install-Package NPredicateBuilder -Version 5.3.0
<PackageReference Include="NPredicateBuilder" Version="5.3.0" />
paket add NPredicateBuilder --version 5.3.0
#r "nuget: NPredicateBuilder, 5.3.0"
// Install NPredicateBuilder as a Cake Addin #addin nuget:?package=NPredicateBuilder&version=5.3.0 // Install NPredicateBuilder as a Cake Tool #tool nuget:?package=NPredicateBuilder&version=5.3.0
NPredicateBuilder
Simple, testable, LINQ queries for dotnet.
Overview
NPredicateBuilder is a way to build LINQ queries and orders with the following:
- 🔬 Small API (2 methods and 2 base classes)
- 📏 Learn in 5 minutes
- 🔑 Easily integrate into LINQ
- ✔️ Write testable queries in seconds
- ♻️ Reuse your queries and orders
Table of Contents
- NPredicateBuilder
Dependencies
- Base Library - None
- EF Library - NET480 - LinqKit.EntityFramework
- EF Library - NET3.1/5/6/7/8 - LinqKit.Microsoft.EntityFrameworkCore
NPredicateBuilder uses LinqKit to expand queries into a properly formed IQueryable.
Installation
The best way is to use NuGet for installation.
In your domain layer.
Install-Package NPredicateBuilder
If you are doing LINQ to Entities, install the following in your data access layer.
Install-Package NPredicateBuilder.EF
Quick Start
Queries
For any entity you wish to query against, create a query class that derives from the BaseQuery class of T, where T is your entity type.
public class PeopleQuery : BaseQuery<People>
{
}
Add single queries with the Add or Or logic by creating methods and returning the query object.
public class PeopleQuery : BaseQuery<People>
{
public PeopleQuery AndNameIs(string name)
{
AddAndCriteria(x => x.Name == name);
return this;
}
public PeopleQuery OrAgeIsOver(int age)
{
AddOrCriteria(x => x.Age > age);
return this;
}
}
Start a query by creating a query class and chaining methods to produce the query you desire.
If using LINQ-to-Entities, your final query must be SQL compatible.
Then create a complex query by chaining them together.
var peopleQuery = new PeopleQuery()
.AndNameIs("brad")
.OrAgeIsOver(10);
Pass your queries and orders to the designated extension method.
var result = ApplicationContext.People
.NPredicateBuilderEFWhere(peopleQuery);
If using plain LINQ-to-Objects, there is the same extension method for the IEnumerable interface.
var result = people.NPredicateBuilderWhere(peopleQuery);
Because it's just an extension method, it behaves like any other LINQ to Objects or LINQ to Entities query.
var result = ApplicationContext.People
.NPredicateBuilderEFWhere(peopleQuery)
.Skip(10)
.Take(15)
.Select(x => new { x.Name, x.Age })
.ToList();
NPredicateBuilder can easily be added to any existing or new codebase, no matter what size!
Orders
Orders follow the same pattern as queries. Create an Order class for an entity and start adding methods.
public class PeopleOrders : BaseOrder<People>
{
public PeopleOrders ByAge()
{
OrderBy(x => x.Age);
return this;
}
public PeopleOrders ThenByNameDescending()
{
ThenByDescending(x => x.Name);
return this;
}
}
Plug your orders into any query you want the same way by utilizing either extension method.
var myOrder = new PeopleOrders()
.ByAge()
.ThenByNameDescending();
var ordered = people
.Skip(10)
.Take(30)
.NPredicateBuilderOrder(myOrder)
.ToList();
Compound Boolean Logic
When you need to combine logical "And" plus "Or" statements into a query you can use the built-in method that allows you to combine multiple queries.
var filtered = new PeopleQuery()
.AndAgeIsOver(10)
.AndNameIs("mike")
.Or(new PeopleQuery()
.AndAgeIsUnder(6)
.AndNameIs("jessica"));
With a logical "Or" between both statements, your query will return any "Mike" over the age of 10 AND any "Jessica" under 6.
Without the Or separator, this query would return nothing since it is impossible for all four statements to evaluate to be true on any person.
The samples provide more examples on how to structure more complex compound queries.
Testing
Unit tests are easy to write for queries and orders.
[TestMethod]
public void Where_Queryable_FiltersCorrectly()
{
_customers = new List<Customer>
{
TestHelper.Billy(),
TestHelper.Bobby(),
};
var query = new CustomerTestQuery().AndNameIsBobby();
var result = _customers.AsQueryable().NPredicateBuilderEFWhere(query);
Assert.AreEqual("Bobby", result.Single().Name);
}
[TestMethod]
public void OrderBy_IEnumerable_OrdersCorrectly()
{
_customers = new List<Customer>
{
TestHelper.Bobby(),
TestHelper.Billy(),
TestHelper.Bobby(),
};
var order = new CustomerTestOrder().ByName();
var result = _customers.NPredicateBuilderOrder(order);
Assert.AreEqual("Billy", result.First().Name);
}
Documentation
More documentation can be viewed in the wiki.
It's only a five-minute read!
FAQ
What is NPredicateBuilder?
NPredicateBuilder is a way to write LINQ queries and orders that can be tested individually and then reused multiple times to cut down on duplication.
Do I need NPredicateBuilder?
If your application is simple and has a minimum amount of simple queries-you may not need it.
NPredicateBuilder was created in mind when you find yourself writing the same where or order statement multiple times you have very complex queries that require testing.
What's the difference between the base library and the EF version?
If you are doing LINQ-to-Objects you only need the base library.
If you are using EntityFramework you need the EF library for NPredicateBuilder to work properly.
How is performance?
Your experience may vary depending on how complex your queries are.
Generally, NPredicateBuilder will be "a little" slower due to each query needing to be expanded. We are talking milliseconds here. Unless your performance requirements are extreme, the difference is not noticeable.
How does NPredicateBuilder work with other LINQ statements?
It works like any other LINQ statement because it's an extension method for either the IEnumerable or IQueryable interfaces.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 is compatible. net5.0-windows was computed. net6.0 is compatible. 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 is compatible. 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. |
.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 is compatible. |
.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
- No dependencies.
-
.NETStandard 2.1
- No dependencies.
-
net5.0
- No dependencies.
-
net6.0
- No dependencies.
-
net7.0
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on NPredicateBuilder:
Package | Downloads |
---|---|
NPredicateBuilder.EF
NPredicateBuilder extensions for Entity Framework. |
GitHub repositories
This package is not used by any popular GitHub repositories.