Filtering
A data-only filtering primitives layer providing filter condition modeling, operator mapping, evaluation, LINQ expression building, and JSON serialization.
Overview
The filtering primitives are a set of plain C# classes, enums, and extension methods that model composable filter definitions.
Unlike other primitives, Filtering contains no Razor components. It provides the data layer used by higher-level filter builder
components such as BbFilterBuilder. You can also use these types directly for programmatic filter construction,
evaluation against in-memory collections, LINQ expression generation for EF Core queries, and JSON serialization for persistence.
Building Filters
A FilterDefinition is a tree of conditions and nested groups combined with a logical operator (AND/OR).
Each FilterCondition targets a field, applies an operator, and holds one or two values.
using BlazorBlueprint.Primitives.Filtering;
// Simple filter with AND conditions
var filter = new FilterDefinition
{
Operator = LogicalOperator.And,
Conditions = new List<FilterCondition>
{
new() { Field = "Name", Operator = FilterOperator.Contains, Value = "John" },
new() { Field = "Age", Operator = FilterOperator.GreaterThan, Value = 18.0 }
}
};
// Nested groups for complex logic
var complexFilter = new FilterDefinition
{
Operator = LogicalOperator.And,
Conditions = new List<FilterCondition>
{
new() { Field = "IsActive", Operator = FilterOperator.IsTrue }
},
Groups = new List<FilterDefinition>
{
new()
{
Operator = LogicalOperator.Or,
Conditions = new List<FilterCondition>
{
new() { Field = "Status", Operator = FilterOperator.Equals, Value = "active" },
new() { Field = "Status", Operator = FilterOperator.Equals, Value = "pending" }
}
}
}
};Defining Filter Fields
FilterField defines metadata for each filterable field, including its type and available options.
The field type determines which operators are available via FilterOperatorHelper.
using BlazorBlueprint.Primitives.Filtering;
var fields = new List<FilterField>
{
new() { Name = "Name", Label = "Name", Type = FilterFieldType.Text },
new() { Name = "Age", Label = "Age", Type = FilterFieldType.Number },
new() { Name = "CreatedDate", Label = "Created", Type = FilterFieldType.Date },
new() { Name = "IsActive", Label = "Active", Type = FilterFieldType.Boolean },
new()
{
Name = "Status", Label = "Status", Type = FilterFieldType.Enum,
Options = new List<SelectOption<string>>
{
new("active", "Active"),
new("inactive", "Inactive"),
new("pending", "Pending")
}
}
};
// Get available operators for a field type
FilterOperator[] textOps = FilterOperatorHelper.GetOperatorsForType(FilterFieldType.Text);
// Get display label (e.g., GreaterThan becomes "is after" for dates)
string label = FilterOperatorHelper.GetOperatorLabel(FilterOperator.GreaterThan, FilterFieldType.Date);
// Check operator characteristics
bool needsValue = !FilterOperatorHelper.IsValuelessOperator(FilterOperator.IsEmpty); // false
bool isRange = FilterOperatorHelper.IsRangeOperator(FilterOperator.Between); // trueEvaluating Filters
Use ToFunc<T>() for client-side in-memory filtering, or ToExpression<T>() for
server-side filtering with EF Core or other IQueryable providers.
using BlazorBlueprint.Primitives.Filtering;
// Client-side filtering with ToFunc<T>
Func<MyItem, bool> predicate = filter.ToFunc<MyItem>(fields);
var filtered = items.Where(predicate).ToList();
// Server-side filtering with ToExpression<T> (EF Core)
Expression<Func<MyItem, bool>> expression = filter.ToExpression<MyItem>(fields);
var results = await dbContext.Items.Where(expression).ToListAsync();JSON Serialization
Filter definitions can be serialized to JSON for persistence (e.g., saved filters) and deserialized back.
using BlazorBlueprint.Primitives.Filtering;
// Serialize to JSON for storage
string json = filter.ToJson();
// Deserialize from JSON
FilterDefinition restored = FilterDefinitionExtensions.FromJson(json);Operators
Available operators depend on the FilterFieldType. Use FilterOperatorHelper
to discover available operators, get display labels, and classify operator behavior.
Text Operators
Equals, NotEquals, Contains, NotContains, StartsWith, EndsWith, IsEmpty, IsNotEmpty
Number Operators
Equals, NotEquals, GreaterThan, LessThan, GreaterOrEqual, LessOrEqual, Between, IsEmpty, IsNotEmpty
Date / DateTime Operators
Equals, NotEquals, GreaterThan (is after), LessThan (is before), GreaterOrEqual, LessOrEqual, Between, InLast, InNext, DateIs, DateIsNot, IsEmpty, IsNotEmpty
Boolean Operators
IsTrue, IsFalse
Enum Operators
Equals, NotEquals, In, NotIn, IsEmpty, IsNotEmpty