NPredicateBuilder.EF 5.3.0

dotnet add package NPredicateBuilder.EF --version 5.3.0
NuGet\Install-Package NPredicateBuilder.EF -Version 5.3.0
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="NPredicateBuilder.EF" Version="5.3.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add NPredicateBuilder.EF --version 5.3.0
#r "nuget: NPredicateBuilder.EF, 5.3.0"
#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.
// Install NPredicateBuilder.EF as a Cake Addin
#addin nuget:?package=NPredicateBuilder.EF&version=5.3.0

// Install NPredicateBuilder.EF as a Cake Tool
#tool nuget:?package=NPredicateBuilder.EF&version=5.3.0

NPredicateBuilder

Simple, testable, LINQ queries for dotnet.

TempIcon

build-status downloads downloads activity

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

Dependencies

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 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 netcoreapp3.1 is compatible. 
.NET Framework net48 is compatible.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
5.3.0 108 1/21/2024
5.2.1 129 12/30/2023
5.2.0 93 12/30/2023
5.1.1 123 6/12/2023
5.1.0 118 6/12/2023
5.0.0 400 7/9/2022
4.0.0 360 1/15/2021
3.1.0 561 4/3/2020
3.0.0 520 9/21/2019