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