Build Criteria - Cheat Sheet
- 20 minutes to read
Tip
The Criteria Operators Cheat Sheet Github repo contains all the code samples used on this page.
AggregateOperand.Avg
Evaluates the average of the values in the collection.
Example 1
Get average value of price property of all orders.
Expression:
CriteriaOperator.FromLambda<Order, double>(x => FromLambdaFunctions.TopLevelAggregate<Order>().Average(c => c.Price));
Input:
Name | Price |
---|---|
Item0 | 10 |
Item1 | 20 |
The result: 15
Example 2
Get list of orders with average order item price more than 100.
Expression:
CriteriaOperator.FromLambda<Order>(x => x.OrderItems.Average(t => t.ItemPrice) > 100);
Input:
Order | OrderItem | OrderItemPrice |
---|---|---|
Order0 | ||
Item0-0 | 10 | |
Item0-1 | 20 | |
Order1 | ||
Item1-0 | 100 | |
Item1-1 | 200 | |
Order2 | ||
Item2-0 | 30 | |
Item2-1 | 40 | |
Order3 | ||
Item3-0 | 300 | |
Item3-1 | 400 |
The result:
Order |
---|
Order1 |
Order3 |
AggregateOperand.Count
Returns the number of objects in a collection.
Example 1
Get amount of all orders.
Expression:
CriteriaOperator.FromLambda<Order, double>(x => FromLambdaFunctions.TopLevelAggregate<Order>().Count());
Input:
Order |
---|
Order0 |
Order1 |
The result: 2
Example 2
Get orders with more than 1 order items.
Expression:
Input:
Order | OrderItem |
---|---|
Order0 | |
Item0-0 | |
Item0-1 | |
Order1 | |
Item1-0 | |
Order2 | |
Item2-0 | |
Item2-1 |
The result:
Order |
---|
Order0 |
Order2 |
Example 3
Get orders that have items with the IsAvailable
property set to ‘True’.
Expression:
CriteriaOperator.FromLambda<Order>(x => x.OrderItems.Count(i => i.IsAvailable == true) > 0);
Input:
Order | OrderItem | IsAvailable |
---|---|---|
Order0 | ||
Item0-0 | False | |
Item0-1 | False | |
Order1 | ||
Item1-0 | True | |
Item1-1 | False | |
Order2 | ||
Item2-0 | False | |
Item2-1 | True |
The result:
Order |
---|
Order1 |
Order2 |
AggregateOperand.Single
Returns a single object from the AggregateOperand.CollectionProperty that matches the specified AggregateOperand.Condition. The collection must be empty or contain exactly one object.
Example 1
Get a property’s value of a specific element from a child collection
Expression:
CriteriaOperator.FromLambda<Order, string>(o => o.OrderItems.SingleOrDefault(oi => oi.ItemPrice == 40).OrderItemName);
Input:
Order | OrderItemName | ItemPrice |
---|---|---|
Order0 | ||
OrderItem1 | 30 | |
OrderItem2 | 40 |
The result: OrderItem2
Example 2
Get a specific element from a child collection.
Expression:
CriteriaOperator.FromLambda<Order, OrderItem>(o => o.OrderItems.SingleOrDefault(oi => oi.ItemPrice == 40));
Input:
Order | OrderItemId | OrderItemName | ItemPrice |
---|---|---|---|
Order0 | |||
0 | OrderItem1 | 30 | |
1 | OrderItem2 | 40 |
The result: 1
Example 3
Get a specific element from a child collection and use it in another expression.
Expression:
CriteriaOperator.FromLambda<OrderItem>(oi => oi.Order == FromLambdaFunctions.FreeJoin<Order>(o => o.OrderItems.Any(oii => oii.ItemPrice == 456)).SingleOrDefault());
Input:
OrderId | Order | OrderItemName | ItemPrice |
---|---|---|---|
1 | Order0 | ||
OrderItem1 | 1 | ||
OrderItem2 | 456 | ||
OrderItem3 | 3 | ||
OrderItem4 | 4 | ||
2 | Order1 | ||
OrderItem5 | 30 | ||
OrderItem6 | 40 |
The result:
OrderItemName | ItemPrice |
---|---|
OrderItem1 | 1 |
OrderItem2 | 456 |
OrderItem3 | 3 |
OrderItem4 | 4 |
AggregateOperand.Exists
Determines whether the number of elements in a collection is greater than zero.
Example
Check whether a collection has items.
Expression:
Input:
Order | OrderItemName |
---|---|
Order0 | |
OrderItem1 | |
OrderItem2 |
The result: True
AggregateOperand.Exists(CriteriaOperator)
Determines whether the number of elements in a collection that match the criteria is greater than zero.
Example
Check whether a collection has elements that match a criteria.
Expression:
CriteriaOperator.FromLambda<Order>(o => o.OrderItems.Any(oi=>oi.ItemPrice==20)); ;
Input:
Order | OrderItemName | ItemPrice |
---|---|---|
Order0 | ||
OrderItem1 | 20 | |
OrderItem2 | 30 |
The result: True
AggregateOperand.Max
Returns the maximum value of a collection.
Example 1
Get the max value from a whole collection.
Expression:
CriteriaOperator.FromLambda<Order, int>(o => o.OrderItems.Max(oi => oi.ItemPrice));
Input:
Order | OrderItemName | ItemPrice |
---|---|---|
Order0 | ||
OrderItem1 | 10 | |
OrderItem2 | 20 |
The result: 20
Example 2
Get the max value from a filtered collection.
Expression:
CriteriaOperator.FromLambda<Order, int>(o => o.OrderItems.Where(oi => oi.IsAvailable == true).Max(oi => oi.ItemPrice)); ;
Input:
Order | OrderItemName | ItemPrice | IsAvailable |
---|---|---|---|
Order0 | |||
OrderItem1 | 10 | False | |
OrderItem2 | 20 | True | |
OrderItem2 | 30 | True | |
OrderItem2 | 40 | False |
The result: 30
AggregateOperand.Min
Returns the minimum value of a collection.
Example 1
Gets the min value from a collection.
Expression:
CriteriaOperator.FromLambda<Order, int>(o => o.OrderItems.Min(oi => oi.ItemPrice));
Input:
Order | OrderItemName | ItemPrice |
---|---|---|
Order0 | ||
OrderItem1 | 10 | |
OrderItem2 | 20 |
The result: 10
Example 2
Get the min value from a filtered collection.
Expression:
CriteriaOperator.FromLambda<Order, int>(o => o.OrderItems.Where(oi => oi.IsAvailable == true).Min(oi => oi.ItemPrice)); ;
Input:
Order | OrderItemName | ItemPrice | IsAvailable |
---|---|---|---|
Order0 | |||
OrderItem1 | 10 | False | |
OrderItem2 | 20 | True | |
OrderItem2 | 30 | True | |
OrderItem2 | 40 | False |
The result: 20
AggregateOperand.Sum
Returns the sum of values from a collection.
Example 1
Get the sum of values from a whole collection
Expression:
CriteriaOperator.FromLambda<Order, int>(o => o.OrderItems.Sum(oi => oi.ItemPrice));
Input:
Order | OrderItemName | ItemPrice |
---|---|---|
Order0 | ||
OrderItem1 | 10 | |
OrderItem2 | 20 |
The result: 30
Example 2
Get the sum of values from a filtered collection.
Expression:
CriteriaOperator.FromLambda<Order, int>(o => o.OrderItems.Where(oi => oi.IsAvailable == true).Sum(oi => oi.ItemPrice)); ;
Input:
Order | OrderItemName | ItemPrice | IsAvailable |
---|---|---|---|
Order0 | |||
OrderItem1 | 10 | False | |
OrderItem2 | 20 | False | |
OrderItem2 | 30 | True | |
OrderItem2 | 40 | True |
The result: 70
BetweenOperator
Determines whether items are within the range of values.
Example
Get items from collection that have a property’s values between specified arguments.
Expression:
//Although there is no LINQ expression that generates the BetweenOperator you can solve this task using the following expression
CriteriaOperator.FromLambda<OrderItem>(oi => oi.ItemPrice >= 10 && oi.ItemPrice <= 30);
Input:
OrderItemName | ItemPrice |
---|---|
OrderItem1 | 10 |
OrderItem2 | 20 |
OrderItem3 | 30 |
OrderItem4 | 40 |
The result:
OrderItemName | ItemPrice |
---|---|
OrderItem1 | 10 |
OrderItem2 | 20 |
OrderItem3 | 30 |
BinaryOperator
Performs a BinaryOperatorType operation between two operands.
Example
Return orders that have price more or equal to 50.
Expression:
Input:
OrderName | Price |
---|---|
Order1 | 30 |
Order2 | 40 |
Order3 | 50 |
Order4 | 60 |
The result:
OrderName | Price |
---|---|
Order1 | 50 |
Order2 | 60 |
ContainsOperator
Checks if a collection contains at least one object matching a specific criteria.
Example
Selects Order objects that contain at least one object in their OrderItems collection with the OrderPrice
property set to 44.
Expression:
// There is no LINQ expression that generates the ContainsOperator you can solve this task using the following expression
CriteriaOperator.FromLambda<Order>(o => o.OrderItems.Any(oi => oi.ItemPrice == 44));
Input:
Order | OrderItem | ItemPrice |
---|---|---|
Order0 | ||
Item0-0 | 10 | |
Item0-1 | 20 | |
Order1 | ||
Item1-0 | 30 | |
Item1-1 | 44 |
The result:
Order |
---|
Order1 |
FunctionOperator.IsNullOrEmpty
Indicates whether a specified operand is a null reference or empty string.
Example
Select an Order with empty descriptions.
Expression:
Input:
Order | Description |
---|---|
Order0 | “The main order” |
Order1 |
The result:
Order |
---|
Order1 |
FunctionOperator.IsNull
Compares the first operand with the NULL value. If a single operand is passed, the function returns true if the operand is null, otherwise, false is returned.
If two operands are passed, the function returns the second operand if the first operand is null; otherwise, the first operand is returned.
Example 1
Select OrderItems with an empty Order property
Expression:
//Although there is no LINQ expression that generates the IsNull operator you can solve this taks using the following expression
CriteriaOperator.FromLambda<OrderItem>(oi => oi.Order == null);
Input:
OrderItemName | Order |
---|---|
OrderItem0 | Order0 |
OrderItem1 |
The result:
OrderItemName |
---|
OrderItem1 |
Example 2
Selects Orders where Description is either null
or has the ‘Wrong value’ value.
Expression:
//Although there is no LINQ expression that generates the IsNull operator you can solve this taks using the following expression
CriteriaOperator.FromLambda<Order>(oi => "WrongValue" == (oi.Description ?? "WrongValue"));
Input:
OrderName | Description |
---|---|
Order0 | “Test description” |
Order1 | “” |
Order2 | “Wrong value” |
The result:
OrderName |
---|
Order1 |
Order2 |
FunctionOperator.Iif
Returns one of several specified values that depend on the values of logical expressions.
Example
Selects orders where ‘OrderColor’ is either ‘Blue’ for ‘Type1’ orders or ‘Orange’ for ‘Type2 orders.
Expression:
CriteriaOperator.FromLambda<Order>(o => o.OrderColor == (o.OrderType == "Type1" ? "Blue" : o.OrderType == "Type2" ? "Orange" : "SomeNullValue"));
Input:
Order | OrderType | OrderColor |
---|---|---|
Order1 | “Type1” | “Red” |
Order2 | “Type1” | “Blue” |
Order3 | “Type2” | “Green” |
Order4 | “Type2” | “Orange” |
The result:
Order |
---|
Order2 |
Order4 |
FunctionOperator String operators
The following function operators are available for strings:
- Trim
- Len
- Substring
- Upper
- Lower
- Concat
- Ascii
- Char
- ToStr
- Replace
- Reverse
- Insert
- CharIndex
- Remove
- StartsWith
- EndsWith
- Contains
- PadLeft
- PadRight
You can read more about these operators here: FunctionOperatorType.
Example 1
Selects Orders
with names that end with 1
.
Expression:
Input:
OrderName |
---|
Order0 |
Order1 |
The result:
OrderName |
---|
Order1 |
Example 2
Selects orders where the string represenation of the Price
property is equal to 20
.
Expression:
Input:
OrderName | Price |
---|---|
Order1 | 10 |
Order2 | 20 |
The result:
OrderName |
---|
Order2 |
Example 3
Selects Orders
whose OrderName
is equal to the Test
and Value
string concatenation.
Expression:
Input:
OrderName |
---|
TestValue |
SomeValue |
The result:
OrderName |
---|
TestValue |
FunctionOperator Numeric operators
There are plenty of Function operators to work with numeric values. Here is the full list:
- Abs
- Sqr
- Cos
- Sin
- Atn
- Exp
- Log
- Rnd
- Tan
- Power
- Sign
- Round
- Ceiling
- Floor
- Max
- Min
- Acos
- Asin
- Atn2
- BigMul
- Cosh
- Log10
- Sinh
- Tanh
- ToInt
- ToLong
- ToFloat
- ToDouble
- ToDecimal
You can read more about these operators here: FunctionOperatorType
Example
Selects Orders where the absolute value of the Price property is greater than 10
Expression:
Input:
OrderName | Price |
---|---|
Order0 | 4 |
Order1 | 11 |
Order2 | -15 |
The result:
OrderName |
---|
Order1 |
Order2 |
FunctionOperator DateTime operators
You can use the following function operators to work with dates:
- LocalDateTimeThisYear
- LocalDateTimeThisMonth
- LocalDateTimeLastWeek
- LocalDateTimeThisWeek
- LocalDateTimeYesterday
- LocalDateTimeToday
- LocalDateTimeNow
- LocalDateTimeTomorrow
- LocalDateTimeDayAfterTomorrow
- LocalDateTimeNextWeek
- LocalDateTimeTwoWeeksAway
- LocalDateTimeNextMonth
- LocalDateTimeNextYear
- LocalDateTimeTwoMonthsAway
- LocalDateTimeTwoYearsAway
- LocalDateTimeLastMonth
- LocalDateTimeLastYear
- LocalDateTimeYearBeforeToday
- IsOutlookIntervalBeyondThisYear
- IsOutlookIntervalLaterThisYear
- IsOutlookIntervalLaterThisMonth
- IsOutlookIntervalNextWeek
- IsOutlookIntervalLaterThisWeek
- IsOutlookIntervalTomorrow
- IsOutlookIntervalToday
- IsOutlookIntervalYesterday
- IsOutlookIntervalEarlierThisWeek
- IsOutlookIntervalLastWeek
- IsOutlookIntervalEarlierThisMonth
- IsOutlookIntervalEarlierThisYear
- IsOutlookIntervalPriorThisYear
- IsThisWeek
- IsThisMonth
- IsThisYear
- IsNextMonth
- IsNextYear
- IsLastMonth
- IsLastYear
- IsYearToDate
- IsSameDay
- InRange
- InDateRange
- IsJanuary
- IsFebruary
- IsMarch
- IsApril
- IsMay
- IsJune
- IsJuly
- IsAugust
- IsSeptember
- IsOctober
- IsNovember
- IsDecember
- DateDiffTick
- DateDiffSecond
- DateDiffMilliSecond
- DateDiffMinute
- DateDiffHour
- DateDiffDay
- DateDiffMonth
- DateDiffYear
- GetDate
- GetMilliSecond
- GetSecond
- GetMinute
- GetHour
- GetDay
- GetMonth
- GetYear
- GetDayOfWeek
- GetDayOfYear
- GetTimeOfDay
- Now
- UtcNow
- Today
- AddTimeSpan
- AddTicks
- AddMilliSeconds
- AddSeconds
- AddMinutes
- AddHours
- AddDays
- AddMonths
You can read more about these operators here: FunctionOperatorType.
Example 1
Selects Orders with OrderDate’s months is greater than 2.
Expression:
Input:
OrderName | OrderDate |
---|---|
Order0 | 15 jan 2022 |
Order1 | 13 mar 2022 |
Order2 | 18 may 2022 |
The result:
OrderName |
---|
Order1 |
Order2 |
Example 2
Selects Orders with OrderDate is equal to 10-mar-2022.
Expression:
var requiredDate = new DateTime(2022, 3, 10);
// ...
CriteriaOperator.FromLambda<Order>(o => o.OrderDate == requiredDate);
Input:
OrderName | OrderDate |
---|---|
Order0 | 15 jan 2022 |
Order1 | 13 mar 2022 |
Order2 | 18 may 2022 |
The result:
OrderName |
---|
Order1 |
Order2 |
Example 3
Selects Order
instances whose OrderDate
is equal to 10-mar-2022
plus 1000 milliseconds.
Expression:
var targetDate = new DateTime(2022, 3, 10).AddMilliseconds(1000);
// ...
CriteriaOperator.FromLambda<Order>(o => o.OrderDate.AddMilliseconds(1000) == targetDate);
GroupOperator
Groups two or more operands with a logical AND or OR.
Example
Return orders that have Price equal to 20 or OrderName equal to ‘Order3’.
Expression:
Input:
OrderName | Price |
---|---|
Order0 | 10 |
Order1 | 20 |
Order2 | 30 |
Order3 | 40 |
The result:
OrderName |
---|
Order1 |
Order3 |
InOperator
Determines if a value matches a value in the specified list.
Example
Get order with the OrderName property ore one of the follows values: ‘Order2’, ‘Order3’,’Description5’.
Expression:
CriteriaOperator.FromLambda<Order, bool>(o => new string[] { "Order2", "Order3", "Description5" }.Contains(o.OrderName));
Input:
OrderName |
---|
Order0 |
Order1 |
Order2 |
Order3 |
The result:
OrderName |
---|
Order2 |
Order3 |
UnaryOperator
Performs unary operations (like NOT or NULL).
Example 1
Return orders that have Price is not between 20 and 30.
Expression:
Input:
OrderName | Price |
---|---|
Order0 | 10 |
Order1 | 20 |
Order2 | 30 |
Order3 | 40 |
The result:
OrderName |
---|
Order0 |
Order3 |
Example 2
Return order items with the Order property references to null
.
Expression:
Input:
OrderItemName | Order |
---|---|
OrderItem0 | null |
OrderItem1 | Order1 |
The result:
OrderItemName |
---|
OrderItem0 |
Complex Scenarios
Complex scenarios for different operators:
Selects Orders with Price equal to 99 and has OrderItems with ItemPrice equal to 10:
Expression:
CriteriaOperator.FromLambda<Order>(o => o.OrderItems.Any(oi => oi.ItemPrice == 10) && o.Price == 99);
Input:
OrderName | Price | OrderItemName | ItemPrice |
---|---|---|---|
Order0 | 99 | ||
OrderItem00 | 2 | ||
OrderItem01 | 4 | ||
Order1 | 99 | ||
OrderItem10 | 5 | ||
OrderItem11 | 10 |
The result:
OrderName |
---|
Order1 |
Selects Orders with OrderItems that has Company with CompanyName equal to ‘Company1’:
Expression:
CriteriaOperator.FromLambda<Order>(o => o.OrderItems.Any(oi => oi.Company.CompanyName == "Company1"));
Input:
OrderName | OrderItemName | CompanyName |
---|---|---|
Order0 | ||
OrderItem00 | ||
Company0 | ||
Company2 | ||
Order1 | ||
OrderItem10 | ||
Company1 | ||
Company3 |
The result:
OrderName |
---|
Order1 |
Selects Orders with OrderDate in the two-week range from the specific date:
Expression:
var targetDate = new DateTime(2022, 8, 9);
// ...
CriteriaOperator.FromLambda<Order>(o => o.OrderDate >= targetDate.AddDays(-14) && o.OrderDate < targetDate);
Input:
OrderName | OrderDate | OrderItemName | ItemPrice |
---|---|---|---|
Order0 | 2022-08-07 | ||
Order1 | 2022-07-07 | ||
Order2 | 2022-08-01 |
The result:
OrderName |
---|
Order0 |
Order2 |
Selects OrderItems with assigned Company and Order.OrderName equal to ‘Order1’:
Expression:
CriteriaOperator.FromLambda<OrderItem>(oi => oi.Order.OrderName == "Order1" && oi.Company != null);
Selects Orders with the maximum OrderDate:
Expression:
CriteriaOperator.FromLambda<Order>(o => o.OrderDate == FromLambdaFunctions.FreeJoin<Order>(selectOrder => selectOrder.OrderColor == "red").Max(resultOrder => resultOrder.OrderDate));
Input:
OrderName | OrderDate | OrderColor |
---|---|---|
Order0 | 2022-08-07 | red |
Order1 | 2022-08-08 | yellow |
Order2 | 2022-08-09 | green |
Order3 | 2022-08-10 | red |
Order4 | 2022-08-10 | yellow |
The result:
OrderName |
---|
Order3 |
Order4 |
Selects Orders with sum of all child Positions’s PositionCount equal to 10:
Expression:
CriteriaOperator.FromLambda<Order>(o => o.OrderItems.Sum(oi => oi.Positions.Sum(p => p.PositionCount)) == 10);
Input:
OrderName | OrderItemName | PositionName | PositionCount |
---|---|---|---|
Order0 | |||
OrderItem00 | |||
Position000 | 2 | ||
Position001 | 3 | ||
OrderItem01 | |||
Position010 | 1 | ||
Position011 | 4 | ||
Order1 | |||
OrderItem10 | |||
Position100 | 10 | ||
Position101 | 20 | ||
OrderItem11 | |||
Position110 | 30 | ||
Position111 | 40 |
The result:
OrderName |
---|
Order0 |
Selects Orders that has OrderItems with OrderDate equal to parent Order’s RegistrationDate:
Expression:
CriteriaOperator.FromLambda<Order>(o => o.OrderItems.Any(oi => oi.RegistrationDate == o.OrderDate));
Input:
OrderName | OrderDate | OrderItemName | RegistrationDate |
---|---|---|---|
Order0 | 2022-08-16 | ||
OrderItem00 | 2022-08-17 | ||
OrderItem01 | 2022-08-18 | ||
Order1 | 2022-08-19 | ||
OrderItem10 | 2022-08-19 | ||
OrderItem11 | 2022-08-20 |
The result:
OrderName |
---|
Order1 |
Selects Orders with Status equal to the ‘Delayed’ enum value:
Expression:
Input:
OrderName | Status |
---|---|
Order0 | Active |
Order1 | Delayed |
The result:
OrderName |
---|
Order1 |
Note
Register enums using the EnumProcessingHelper.RegisterEnum method.
Selects OrderItems with Order equal to the specific Order object:
Expression:
var obj = uow.GetObjectByKey<Order>(2);
var criterion = CriteriaOperator.FromLambda<OrderItem>(x => x.Order == obj);
Escaping and square brackets
Generally, you do not need to use square brackets when you build string criteria operators.
The following criteria are equal:
CriteriaOperator.Parse("Contains(OrderName,'der1')");
CriteriaOperator.Parse("Contains([OrderName],'der1')");
You need to use square brackets if your property names match criteria language keywords:
The correct criterion:
CriteriaOperator.Parse("Contains([Contains],'ike0')");
Alternatively, you can mark a keyword-like field name with an escape character (@ sign):
CriteriaOperator.Parse("Contains(@Contains, 'ike0')");
The wrong criterion that raises an exception:
CriteriaOperator.Parse("Contains(Contains,'ike0')");
Note that the recommended way to build a criterion is to use LINQ-Like Criteria Syntax:
CriteriaOperator.FromLambda<Order>(o => o.Contains.Contains("ike0"));
XAF-specific Criteria Features
Current Object Parameter
The Current Object Parameter allows you to access properties of the current object. The following snippet shows how to filter a lookup by a linked MyTaskDepartment
object. The lookup shows contacts where the ContactDepartment
property value is the same as the current MyTaskDepartment
property of MyTask
:
public class MyTask : BaseObject {
// ...
[DataSourceCriteria("ContactDepartment = '@This.MyTaskDepartment.Oid'")]
public Contact NewContact3 {
get => newContact3;
set => SetPropertyValue(nameof(NewContact3), ref newContact3, value);
}
// ...
public Department MyTaskDepartment {
get => myTaskDepartment;
set => SetPropertyValue(nameof(MyTaskDepartment), ref myTaskDepartment, value);
}
// ...
}
public class Contact : BaseObject {
// ...
public Department ContactDepartment {
get => contactDepartment;
set => SetPropertyValue(nameof(ContactDepartment), ref contactDepartment, value);
}
// ...
}
CurrentUserId
The CurrentUserId() operator returns the identifier of the current user. The following snippet shows how to use this operator to filter a reference property’s lookup:
Expression:
public class MyTask : BaseObject {
// ...
Contact _assignedTo;
[Association("Contact-Tasks")]
[DataSourceCriteria("Owner.Oid==CurrentUserId()")]
public Contact AssignedTo {
get { return _assignedTo; }
set { SetPropertyValue(nameof(AssignedTo), ref _assignedTo, value); }
}
// ...
}
public class Contact : BaseObject {
// ...
public ApplicationUser Owner {
get => owner;
set => SetPropertyValue(nameof(Owner), ref owner, value);
}
// ...
}
IsCurrentUserId
The IsCurrentUserId(oid) operator returns True
if the current user has the specified identifier. The following snippet shows how to use this operator to filter a reference property’s lookup:
Expression:
public class MyTask : BaseObject {
// ...
[DataSourceCriteria("IsCurrentUserId(Owner.Oid)")]
public Contact NewContact1 {
get => newContact1;
set => SetPropertyValue(nameof(NewContact1), ref newContact1, value);
}
// ...
}
public class Contact : BaseObject {
// ...
public ApplicationUser Owner {
get => owner;
set => SetPropertyValue(nameof(Owner), ref owner, value);
}
// ...
}
IsCurrentUserInRole
The IsCurrentUserInRole(‘rolename’) operator determines whether the currently logged on user is assigned to a role with the specific name. The following snippet shows how to filter a reference property’s lookup;
Expression:
public class MyTask : BaseObject {
// ...
[DataSourceCriteria("IsCurrentUserInRole('Default')")]
public Contact NewContact2 {
get => newContact2;
set => SetPropertyValue(nameof(NewContact2), ref newContact2, value);
}
// ...
}
public class Contact : BaseObject {
// ...
public ApplicationUser Owner {
get => owner;
set => SetPropertyValue(nameof(Owner), ref owner, value);
}
// ...
}
IsNewObject
The IsNewObject(obj) operator indicates whether the specified object was created but not saved to the database. The following snippet shows how to show an action for new objects only. @This
is the Current Object Parameter.
Expression:
myAction1.TargetObjectsCriteria = "IsNewObject(@This)";
EF Core and XPO ORM-specific Criteria Features
Free Joins
Free Joins allow you to join persistent objects conditionally, use object properties to calculate aggregate functions against matching objects, and return aggregate values as ajoin result.
Example 1
Get orders are referenced in the FreeOrderItem
classes to ensure that the sum of all related FreeOrderItem
objects is more than 2
.
Expression:
CriteriaOperator.FromLambda<Order>(o => FromLambdaFunctions.FreeJoin<FreeOrderItem>(oi => oi.Order.Oid == o.Oid).Count() > 2);
Input:
FreeOrderItem | Order |
---|---|
FreeItem0 | Order0 |
FreeItem1 | Order0 |
FreeItem2 | Order1 |
FreeItem3 | Order1 |
FreeItem4 | Order1 |
The result: OrderItem1
If two classes have an association between them, FreeJoins loads all data from a database to join these classes. We recommend that you use association properties instead. You can rewrite the example above as follows (the Order
and OrderItem
classes have an association between them):
Expression:
Example 2
Get orders that are referenced in the FreeOrderItem
classes to ensure that an order’s OrderDate
is equal to the max FreeOrderDate
from the order’s related FreeOrderItems
.
Expression:
CriteriaOperator.FromLambda<Order>(o => o.OrderDate == FromLambdaFunctions.FreeJoin<FreeOrderItem>(oi => oi.FreeOrderOwnerName == o.OrderOwnerName).Max(oi => oi.FreeOrderDate));
Input:
Order | OrderDate | FreeOrderItem | FreeOrderDate |
---|---|---|---|
Order1 | 3-Nov-22 | ||
FreeItem0 | 2-Nov-22 | ||
FreeItem1 | 1-Nov-22 | ||
Order2 | 25-Nov-22 | ||
FreeItem2 | 14-Nov-22 | ||
FreeItem3 | 25-Nov-22 |
The result: Order2
Example 3
For each owner, get the latest (youngest) FreeOrderItems
.
Expression:
CriteriaOperator.FromLambda<Order>(parentO => parentO.OrderDate == FromLambdaFunctions.FreeJoin<Order>(childO => childO.OrderOwnerName == parentO.OrderOwnerName).Max(o => o.OrderDate));
Input:
Order | OrderDate | Owner |
---|---|---|
Order0 | 3-Nov-22 | Owner1 |
Order1 | 4-Nov-22 | Owner1 |
Order2 | 6-Nov-22 | Owner2 |
Order3 | 5-Nov-22 | Owner2 |
The result: Order1, Order2
XAF Applications
Free Joins-based criteria are also supported for XAF UI and Web API Service applications powered by EF Core for data access. This feature is not supported in non-XAF applications.
Upcasting
Upcasting allows you to use properties from derived classes.
Example
Selects orders that are ExtendedOrder
class instances (descendants of the Order
class) and has ExtendedDescription
equal to "description1"
:
Expression:
CriteriaOperator.FromLambda<Order>(o => ((ExtendedOrder)o).ExtendedDescription == "description1");
Filter by Type
To filter objects by type, use one of the following approaches:
The ObjectType service field. Refer to the following topic for more information: When and Why XPO Extends the Database Schema.
IsExactType
function operator:Expression:
IsInstanceOfType
function operator:Expression: