LINQ-Like Criteria Syntax
- 3 minutes to read
The CriteriaOperator class implements the CriteriaOperator.FromLambda method. Use this method to create type-safe criteria expressions from lambda expressions.
// Regular criteria syntax
CriteriaOperator opParsed = CriteriaOperator.Parse("[Name] = 'Alex'");
// LINQ-style criteria syntax typed
CriteriaOperator opLambda = CriteriaOperator.FromLambda<Customer, int>(customer => customer.Orders.Count())
// LINQ-style criteria syntax bool only
CriteriaOperator opLambda = CriteriaOperator.FromLambda<Customer>(customer => customer.Name == "Alex")
Overview
CriteriaOperator.FromLambda
allows you to build criteria in an intuitive manner:
CriteriaOperator.FromLambda<Customer>(customer => customer.Age > 10);
CriteriaOperator.FromLambda<Customer>(customer => customer.Name == "Alex");
CriteriaOperator.FromLambda<Customer>(customer => customer.IsLongterm);
CriteriaOperator.FromLambda
supports LINQ extension methods:
CriteriaOperator.FromLambda<Supplier>(supplier => supplier.Products.Any());
CriteriaOperator.FromLambda<Supplier>(supplier => supplier.Products.All());
CriteriaOperator.FromLambda<Supplier>(supplier => supplier.Products.Average(product => product.Price) > 100 );
Supported Features
Built-in and Custom Functions
CriteriaOperator.FromLambda
supports built-in functions of the String, Math, Convert, DateTime, DateOnly, and TimeOnly types.
CriteriaOperator.FromLambda<Shape>(Shape => Shape.Angle < Math.Acos(value));
CriteriaOperator.FromLambda<Customer>(customer => customer.Name.Trim() = 'Alex');
You can implement custom functions and use them to build criteria operators. See How to: Implement a Custom Criteria Language Function Operator for more information.
static class MyCustomAddFunction : ICustomFunctionOperator {
string Name {
get { return "MyCustomAdd"; }
}
// Name must match the Name string
public static int MyCustomAdd(int a, int b){
}
// Interface implementation
}
Built-in and Custom Aggregate Functions
CriteriaOperator.FromLambda
supports both custom and standard (Min
, Max
, Sum
, Avg
, Single
, Exists
, and Count
) aggregate functions.
CriteriaOperator.FromLambda<Supplier>(supplier => supplier.Products.CountDistinct < 10);
To use custom aggregates, implement an extension method to the IEnumerable
interface in addition an ICustomAggregate
interface implementation.
public class CountDistinctCustomAggregate : ICustomAggregate {
// implementation
}
static class CountDistinctCustomAggregateExtension : IEnumerable {
int CountDistinct(this IEnumerable instance) {
// implementation
}
}
FromLambdaFunctions Helper
Use the FromLambdaFunction helper class to create advanced criteria. This class exposes functions that can be used within the CriteriaOperator.FromLambda
method.
Not Type-Safe Custom Functions Including Non-Deterministic
// Creates the following expression: FirstOrderDate([Order])
CriteriaOperator.FromLambda<Customer, DateTime>(customer =>
FromLambdaFunctions.CustomFunction<DateTime>("FirstOrderDate", customer.Order));
// Creates the following expression: CustomNonDeterministic('FirstOrderDate', [Order])
CriteriaOperator.FromLambda<Customer, DateTime>(customer =>
FromLambdaFunctions.CustomFunctionNonDeterministic<DateTime>("FirstOrderDate", customer.Order));
Tip
A component that consumes the resulting FunctionOperator may assume that a function always returns the same result for the same input values. Use the CustomNonDeterministic
method if a result of a custom function is not predictable.
Top Level Aggregate
All built-in Aggregates (like Count
, Exists
, and others) are supported:
CriteriaOperator.FromLambda<Customer, int>(customer => FromLambdaFunctions.TopLevelAggregate<Customer>().Count());
CriteriaOperator.FromLambda<Customer, int>(customer => FromLambdaFunctions.TopLevelAggregate<Customer>().Max(im => im.IntProperty));
Free Join
CriteriaOperator.FromLambda<Customer, bool>(customer => FromLambdaFunctions.FreeJoin<Order>(om => (customer.IntProperty == customer.RefProperty) && (om.IntProperty > 10)).Any());
How It Works
CriteriaOperator.FromLambda
is designed to build criteria expressions in a LINQ notation. Do not use CriteriaOperator.FromLambda
to convert LINQ expressions to Criteria expressions.
// This code throws an exception
CriteriaOperator fromLambda = CriteriaOperator.FromLambda<Customer, IEnumerable>(customer => customer.Orders.OrderBy(tm => tm.Name));
Important
CriteriaOperator.FromLambda
does not support all possible LINQ expressions as our criteria language and LINQ are not fully compatible. For instance, GroupBy
, OrderBy
, and other LINQ methods for filtering are not supported.