JoinOperand Class
An operator that joins persistent objects on a specified condition, and calculates aggregate functions against matching objects.
Namespace: DevExpress.Data.Filtering
Assembly: DevExpress.Data.v24.1.dll
NuGet Package: DevExpress.Data
Declaration
Related API Members
The following members return JoinOperand objects:
Remarks
The JoinOperand works only with eXpress Persistent Objects. Use the JoinOperand to build criteria and calculate aggregate functions using the properties of persistent objects without explicitly defined associations. Persistent objects applied to the current JoinOperand are called parent objects for the join. To specify the type of persistent objects to be joined with parent objects, use the JoinOperand.JoinTypeName property.
To access parent object properties in a join condition, use the Parent Relating Operator.
The JoinOperand does the following:
- Joins the objects on a condition specified via the JoinOperand.Condition property.
- Calculates aggregate functions using expressions created with property values of matching objects. To specify the aggregate function and aggregated expression, use the JoinOperand.AggregateType and JoinOperand.AggregatedExpression properties.
This example demonstrates how to load all employees who can issue refunds (the Employee and User table should have a one-to-one relationship).
using DevExpress.Xpo;
using DevExpress.Data.Filtering;
// ..
/* create via CriteriaOperator.Parse */
// string expr = "[<User>][[Oid] = [^.Oid] && [Permissions][[Action] = ?]]";
// CriteriaOperator filter = CriteriaOperator.Parse(expr, "Issue Refunds");
/* create via constructor */
CriteriaOperator joinCondition = new OperandProperty(nameof(Employee.Oid)) == new OperandProperty($"^.{nameof(User.Oid)}");
CriteriaOperator filterClause = new ContainsOperator(
collectionProperty: new OperandProperty(nameof(User.Permissions)),
condition: new OperandProperty(nameof(Permission.Action)) == new OperandValue("Issue Refunds")
);
CriteriaOperator filter = new JoinOperand(
joinTypeName: nameof(User),
condition: joinCondition & filterClause
);
XPCollection<Employee> employees = new XPCollection<Employee>(session, filter);
If a criteria contains types from different namespaces, the JoinOperand.JoinTypeName
property should contain the full type name with its namespace, for example, as follows:
"[<Application.SomeNamespace.Customers>][^.GroupID = GroupID].Count() > 1
and [<Application.OtherNamespace.Orders>][^.EmployeeID = EmployeeID].Count() > 50"
Refer to the Free Joins help topic for more information on how to use the JoinOperand.
Note
- To improve performance, we recommend that you not use the JoinOperand when filtering or sorting the XPCollection on the client side since this increases the number of queries sent to the server.
- JoinOperand may produce null instead of zero for an empty collection on a server side.
Tip
You can find examples in the following article: Build Criteria - Cheat Sheet.