KB Article A1108
Visible to All Users

How to introduce some properties and logic into my many-to-many relation

Description:
I have a main FamilyMember class. I want to figure out how to define a marriage between two different FamilyMember objects. I also have some more information that I would like to store about a marriage (date, place, etc.). Also the system needs to be able to support multiple marriages for any FamilyMember object. Ideally I would like the system to restrict a marriage relationship to only two FamilyMember objects. How can I define a custom many to many relationship between two different objects in the same class? Also, how can I define these associations?

Answer:
We would advise you to create a many-to-many association between the FamilyMember and Marriage classes and introduce a new class which will control marriages:

C#
public class FamilyMember : XPObject { protected override void BeforeSave() { base.BeforeSave(); MarriagesController.CheckFamilyMember(this); } public string FirstName; public string LastName; [Association("FamilyMember-Marriages", typeof(Marriage))] public XPCollection Marriages { get { return GetCollection("Marriages"); } } } public class Marriage : XPObject { protected override void BeforeSave() { base.BeforeSave(); MarriagesController.CheckMarriage(this); } public string Place; public DateTime Date; [Association("FamilyMember-Marriages", typeof(FamilyMember))] public XPCollection Partners { get { return GetCollection("Partners"); } } } public class MarriagesController { public static MarriagesController CurrentController = new MarriagesController(); public static void CheckFamilyMember(FamilyMember familyMember) { CurrentController.Check(familyMember); } public static void CheckMarriage(Marriage marriage) { foreach(FamilyMember partner in marriage.Partners) { CheckFamilyMember(partner); } } public virtual void Check(FamilyMember familyMember) {} }

Now you can control the marriage rules via the CurrentController property.
For instance, you can check the number of people participating and count the number of marriages:

C#
public class MyMarriagesController : MarriagesController { public override void Check(FamilyMember familyMember) { if (familyMember.Marriages.Count > 1) { throw new Exception("..."); } foreach(Marriage marriage in familyMember.Marriages) { if (marriage.Partners.Count != 2) { throw new Exception("..."); } } } }

Another way is to create your own persistent object for this many-to-many relation and implement the necessary rules within its BeforeSave method:

C#
public class FamilyMemberToMarriageLink : XPObject { protected override void BeforeSave() { base.BeforeSave(); //... } public FamilyMember FamilyMember; public Marriage Marriage; }

See also:
How to change the name of the underlying table and columns for a many-to-many relationship
What is the best solution for mapping a many-to-many relation to an existing database?
How to delete an object which is participating in a many-to-many relation

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.