Skip to main content
.NET 6.0+

How to: Use the ContainsOperator for Objects in a Many-to-Many Relationship

  • 3 minutes to read

The ContainsOperator checks if an optionally filtered collection contains at least one object. The following code shows the declaration of the User and Role persistent objects with collection properties connected using a many-to-many relationship:

public class User : XPObject
{
    public User() : base() { }
    public User(Session session) : base(session) { }

    string name;
    public string Name {
        get { return name; }
        set { SetPropertyValue<string>(nameof(Name), ref name, value); }
    }

    [Association("User-Role")]
    public XPCollection<Role> Roles { 
        get { return GetCollection<Role>(nameof(Roles)); } 
    }
}

public class Role : XPObject
{
    public Role() : base() { }
    public Role(Session session) : base(session) { }

    string roleName;
    public string RoleName {
        get { return roleName; }
        set { SetPropertyValue<string>(nameof(RoleName), ref roleName, value); }
    }

    [Association("User-Role")]
    public XPCollection<User> Users {
        get { return GetCollection<User>(nameof(Users)); }
    }
}

The following code examples demonstrate different ways to get a collection of users, filtered depending on their roles, using the ContainsOperator:

  • Obtaining all users:

    XPCollection<User> users = new XPCollection<User>(session1);
    
  • Obtaining users that belong to a role named “Developer”:

    XPCollection<User> developers = new XPCollection<User>(session1, 
        new ContainsOperator(nameof(User.Roles), new BinaryOperator(nameof(Role.RoleName), "Developer")));
    
  • Obtaining users that belong to a specific role, using a loaded Role object:

    Role managerRole = session1.FindObject<Role>(new BinaryOperator(nameof(Role.RoleName), "Manager"));
    XPCollection<User> managers = new XPCollection<User>(session1, 
        new ContainsOperator(nameof(User.Roles), new BinaryOperator("This", managerRole)));
    
  • Obtaining users that belong to the “Developer” role and whose name starts with “Smith”:

    XPCollection<User> users = new XPCollection<User>(session1,
        new GroupOperator(GroupOperatorType.And, new CriteriaOperator[] {
            new ContainsOperator(nameof(User.Roles), new BinaryOperator(nameof(Role.RoleName), "Developer")),
            new FunctionOperator(FunctionOperatorType.StartsWith, new OperandProperty(nameof(User.Name)), new OperandValue("Smith"))
        })
    );
    

    The following code has the same effect as above but uses the CriteriaOperator.Parse method:

    XPCollection<User> users = new XPCollection<User>(session1, 
        CriteriaOperator.Parse("[Roles][[RoleName] = ?] And StartsWith([Name], ?)", "Developer", "Smith"));
    
  • Returning a Boolean value that indicates whether there are any items in the Orders collection.

    CriteriaOperator criteria = new AggregateOperand("Orders", Aggregate.Count) > 0;
    // or
    CriteriaOperator criteria = new OperandProperty("Orders")[null].Count() > 0;
    
See Also