KB Article A1016
Visible to All Users

How to set query criteria for a collection which is a collection property of a persistent object

Description:
I have two classes: Product and Component which are linked by a one-to-many relation. I want to be able to return a subset of all the components that are associated with a product. Is there a way to set the criteria for an XPcollection that is a part of an association like this?

Answer:
Beginning with the v2011 vol2 release (and also in XPO v1) you can apply criteria to an associated collection via its Criteria property.
A recommended solution is to modify criteria when a collection property value is requested for the first time:

C#
public class Product : XPObject { //... private bool isFirstCallForComponents = true; [Association("Product-Components", typeof(Component))] public XPCollection Components { get { XPCollection result = GetCollection("Components"); if (isFirstCallForComponents && Filtering.Enabled) { GroupOperator criteria = new GroupOperator(); criteria.OperatorType = GroupOperatorType.And; criteria.Operands.Add(result.Criteria); criteria.Operands.Add(new BinaryOperator("Name", "%" + Name + "%", BinaryOperatorType.Like)); result.Criteria = criteria; isFirstCallForComponents = false; } return result; } } }

In legacy XPO versions, changing the associated collection's Criteria property is prohibited. In these versions, to return a subset of an associated collection you need to create a new collection and set its Criteria property so as to return the required data subset. If you introduce a property that returns this collection, do not mark it with the Association attribute.

C#
public class Product : XPObject { //... public XPCollection SelectedComponents { get { CriteriaOperator criteria1 = new BinaryOperator("Product", this); CriteriaOperator customCriteria = null; if (Filtering.Enabled) customCriteria = new BinaryOperator("Name", "Xtra%", BinaryOperatorType.Like); XPCollection result = new XPCollection(typeof(Component), new GroupOperator(GroupOperatorType.And, criteria1, customCriteria)); return result; } } }

See attached project for more details.
Or, if you plan to add the same criteria to many collection properties, you can write your own XPOneToManyCollection descendant and extend the default criteria within its constructor.
See also:
How to define a strongly typed collection property
What criteria should I use to get objects for a collection property which is empty?
How to construct complex queries
How to filter a collection by an associated objects' properties

Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.