Skip to content

Releases: pdevito3/QueryKit

v1.14.0

Choose a tag to compare

@pdevito3 pdevito3 released this 04 Mar 03:54

What's Changed

New Contributors

Full Changelog: v1.13.0...v1.14.0

v1.13.0

Choose a tag to compare

@pdevito3 pdevito3 released this 19 Feb 00:30

What's Changed

Full Changelog: v1.12.1...v1.13.0

v1.12.1

Choose a tag to compare

@pdevito3 pdevito3 released this 07 Jan 02:15

Fixes

Fixed NullReferenceException when using case-insensitive operators on nullable strings (#100)

Case-insensitive string operators now correctly handle null values instead of throwing NullReferenceException.

Affected operators: @=, ==, !=, _=, -=, !@=, !=, !_-=, ^^, !^^

Before (broken):

var people = new List<Person>
{
    new() { Email = null },
    new() { Email = "user@gmail.com" }
};

// This threw NullReferenceException
var result = people.ApplyQueryKitFilter("""Email @=* "gmail" """);

After (fixed):

// Now works correctly - returns only the person with "gmail" in their email
var result = people.ApplyQueryKitFilter("""Email @=* "gmail" """);
// Returns: [{ Email = "user@gmail.com" }]

Behavior:

  • Positive operators (@=, ==, _=, _-=, ^^*): null values are treated as non-matching
  • Negative operators (!=, !@=, !=*, !-=, !^^): null values are included in results (since null ≠ any value)

This fix applies to both IQueryable (database queries) and IEnumerable (in-memory filtering) scenarios.

v1.12.0

Choose a tag to compare

@pdevito3 pdevito3 released this 13 Dec 14:41

Features

Property Depth Limiting

Added the ability to control the maximum depth of nested property access in filters and sorts. This helps protect against deeply nested queries when exposing QueryKit to external consumers.

Usage

// Limit nesting to 2 levels globally
var config = new QueryKitConfiguration(settings =>
{
    settings.MaxPropertyDepth = 2;
});

// "Author.Name" works (depth 1)
// "Author.Address.City" works (depth 2)
// "Author.Address.Country.Name" throws QueryKitPropertyDepthExceededException (depth 3)

Override the global limit for specific properties:

var config = new QueryKitConfiguration(settings =>
{
    settings.MaxPropertyDepth = 1;
    settings.Property<Book>(x => x.Author).HasMaxDepth(2); // Allow deeper nesting for Author
});

v1.11.1

Choose a tag to compare

@pdevito3 pdevito3 released this 24 Nov 13:35

Fixes

Sorting

Sorting by nested navigation properties now handles null intermediate objects gracefully, preventing NullReferenceException when using in-memory collections.

Before (v1.11.0)

  // Would throw NullReferenceException if Player is null
  var sorted = stats
      .ApplyQueryKitSort("MatchPlayer.Player.LastName asc")
      .ToList(); // 💥 NullReferenceException

After (v1.12.0)

  // Now works - null navigation properties are handled safely
  var sorted = stats
      .ApplyQueryKitSort("MatchPlayer.Player.LastName asc")
      .ToList(); // ✅ Works! Nulls sort first in ASC, last in DESC

Details

  • Null intermediate navigation properties now sort as null values rather than throwing
  • Database queries (IQueryable) continue to work as before via EF Core's LEFT JOIN handling
  • In-memory collections (IEnumerable) now behave consistently with database queries
  • For custom null coalescing logic, DerivedProperty remains available:
  var config = new QueryKitConfiguration(c =>
  {
      c.DerivedProperty<PlayerStat>(x =>
          x.MatchPlayer.LastName ??
          (x.MatchPlayer.Player != null ? x.MatchPlayer.Player.LastName : "Unknown"))
          .HasQueryName("playerName");
  });

v1.11.0

Choose a tag to compare

@pdevito3 pdevito3 released this 13 Nov 02:07

New Feature: Property List Grouping

Property list grouping is a powerful new syntax that allows you to apply a single comparison operation across multiple properties, making it dramatically easier to search for values across multiple fields without writing repetitive conditions.

Instead of writing verbose, repetitive filters like this:

var input = """FirstName @=* "paul" || LastName @=* "paul" || Email @=* "paul" """;

You can now write this:

var input = """(FirstName, LastName, Email) @=* "paul" """;

v1.10.0

Choose a tag to compare

@pdevito3 pdevito3 released this 12 Nov 00:59

Full Changelog: v1.9.8...v1.10.0

v1.9.8

Choose a tag to compare

@pdevito3 pdevito3 released this 29 Oct 01:22

Full Changelog: v1.9.7...v1.9.8

v1.9.7

Choose a tag to compare

@pdevito3 pdevito3 released this 28 Sep 20:05

Full Changelog: v1.9.6...v1.9.7

v1.9.6

Choose a tag to compare

@pdevito3 pdevito3 released this 28 Sep 19:20

Full Changelog: v1.9.5...v1.9.6