Home > CRM, Javista, Microsoft Dynamics > CRM 4.0 Relationships explained, many to many

CRM 4.0 Relationships explained, many to many

Relationships in CRM 4.0 are quite powerful but hard to understand at first. There are so many moving parts tied to so many places that it is sometimes difficult to predict what the actual outcome is. So here is my attempt to explain a bit further what the relationships enhancements were in CRM 4.0. To start with let’s explain with a diagram what relationship types are available. Note that to determine the actual feasibility of a relationship (e.g. it may be the case that a specific relationship is not possible between an entity pair) you can use our APIs described here.

Relationships CRM 4.0

As you can see, the above gives you an enormous amount of flexibility on the types of relationships that you can model in CRM 4.0. Now let’s take a look at specific CRM 4.0 enhancements.


We performed a huge redesign of relationships in our backend. The major architectural changes were that we introduced the notion of many-to-many relationships and self referential relationships. To enable many-to-many relationships we implement intersect entities under the covers. To enable self referential relationships we added a couple of checks to prevent circular parental references and we also redid portions of several system relationships that were hardcoded to be metadata driven to enable system to system and multiple relationships.


One of the biggest requests that we had for CRM 4 was to enable customization of the labels that get displayed as part of relationships; furthermore, sometimes relationship are only used as a logical construct for backend operations and aren’t meant to be displayed; hence the ability to “hide” portions of the UI related to relationships was also a requirement. To accomplish all the above we introduced several metadata attributes that control the display behaviors of relationships.

· This screencast walks you to the creation of a simple N:N relationship and describes how different pieces relate to the UI.


Of course we had to provide means for programmers to take advantage of all the niceties that we implemented so we had to introduce a couple of new message and attributes and make some changes in the way fetchXml process relationships. Details are on the SDK but here are a couple of quick examples.

Creating new relationships

Yep, you can create brand new relationships (metadata) programmatically using the metadata API. Here is an example on how to create a Many-to-Many relationship. The CrmUtils class is just a wrapper class that a colleague created to create a label for only one language, 1033-English in this case (as you know CRM 4.0 is Multi Language enabled).

public static void createManyToManyTest(MetadataService metadataService)


ManyToManyMetadata manyToMany = new ManyToManyMetadata();

manyToMany.SchemaName = “new_relationship_name”;

manyToMany.IntersectEntityName = “new_intersect_name”;

//Side A

manyToMany.Entity1LogicalName = “account”;

manyToMany.Entity1AssociatedMenuBehavior = new CrmAssociatedMenuBehavior();

manyToMany.Entity1AssociatedMenuBehavior.Value = AssociatedMenuBehavior.UseLabel;

manyToMany.Entity1AssociatedMenuGroup = new CrmAssociatedMenuGroup();

manyToMany.Entity1AssociatedMenuGroup.Value = AssociatedMenuGroup.Details;

manyToMany.Entity1AssociatedMenuLabel = CrmUtils.CreateSingleLabel(“SIDE A pointing to Side B”, 1033);

manyToMany.Entity1AssociatedMenuOrder = new CrmNumber();

manyToMany.Entity1AssociatedMenuOrder.Value = 15001;

//Side B

manyToMany.Entity2LogicalName = “contact”;

manyToMany.Entity2AssociatedMenuBehavior = new CrmAssociatedMenuBehavior();

manyToMany.Entity2AssociatedMenuBehavior.Value = AssociatedMenuBehavior.UseLabel;

manyToMany.Entity2AssociatedMenuGroup = new CrmAssociatedMenuGroup();

manyToMany.Entity2AssociatedMenuGroup.Value = AssociatedMenuGroup.Details;

manyToMany.Entity2AssociatedMenuLabel = CrmUtils.CreateSingleLabel(“SIDE B pointing to Side A”, 1033);

manyToMany.Entity2AssociatedMenuOrder = new CrmNumber();

manyToMany.Entity2AssociatedMenuOrder.Value = 15001;

CreateManyToManyRequest manyToManyRequest = new CreateManyToManyRequest();

manyToManyRequest.IntersectEntitySchemaName = manyToMany.IntersectEntityName;

manyToManyRequest.ManyToManyRelationship = manyToMany;



Adding records to a relationship

To add a new record to a many-to-many relationship you can use the following code. A similar code can be used to remove a record, just use DisassociateEntities message request/response instead of AssociateEntities.

Note that working with N:N relationships is slightly different than working with a One-to-many relationship (for the later you use SetRelated and RemoveRelated messages instead).

public static void addRelatedTest(TitanMiscTests.CrmSdk.CrmService service)


//Links (relates) an account record to a lead record in a manyToMany relationship

Moniker moniker1 = new Moniker();

moniker1.Name = “account”;

moniker1.Id = new Guid(“4BD77CC1-8D6B-DC11-B026-0017A41E8C1D”);

Moniker moniker2 = new Moniker();

moniker2.Name = “lead”;

moniker2.Id = new Guid(“D1CAB380-C56B-DC11-B026-0017A41E8C1D”);

AssociateEntitiesRequest request = new AssociateEntitiesRequest();

request.Moniker1 = moniker1;

request.Moniker2 = moniker2;

request.RelationshipName = “new_account_lead_custom”;



Retrieving relationships

The following fetch will retrieve all the leads associated with account with name “Foo” in the custom relationship whose intersect entity is “new_account_lead_custom”.

public static void retrieveEntitiesViaFetch(TitanMiscTests.CrmSdk.CrmService service)


string linkFetch = @”<fetch version=””1.0″” output-format=””xml-platform”” mapping=””logical”” distinct=””true””>

<entity name=””lead””>

<attribute name=””fullname””/>

<order attribute=””fullname”” descending=””true””/>

<link-entity name=””new_account_lead_custom”” from=””leadid”” to=””leadid”” visible=””false”” intersect=””true””>

<link-entity name=””account”” from=””accountid”” to=””accountid”” alias=””aa””>

<filter type=””and””>

<condition attribute=””name”” operator=””eq”” value=””Foo””/>






string result = service.Fetch(linkFetch);



The same query can be accomplished using QueryExpression as follows, note how the query is constructed from bottom to top when compared with fetchXml.

public static void retrieveEntityListFromManyToMany(TitanMiscTests.CrmSdk.CrmService service)


//This code will retrieve a list of “leads” associated with the entity “Foo” on the relationship whose intersect entity is “new_account_lead_custom”

//Filter by the specific record that we are looking for

//(In this example we assume that there are no other accounts with the name Foo, otherwise

// if would be recommended to use the account “id” instead of the name.

ConditionExpression conditionName = new ConditionExpression();

conditionName.AttributeName = “name”;

conditionName.Operator = ConditionOperator.Equal;

conditionName.Values = new object[1];

conditionName.Values[0] = “Foo”;

FilterExpression selectByName = new FilterExpression();

selectByName.Conditions = new ConditionExpression[] { conditionName };

//Create nested link entity and apply filter criteria

LinkEntity nestedLinkEntity = new LinkEntity();

nestedLinkEntity.LinkToEntityName = “account”;

nestedLinkEntity.LinkFromAttributeName = “accountid”;

nestedLinkEntity.LinkToAttributeName = “accountid”;

nestedLinkEntity.LinkCriteria = selectByName;

//Create the nested link entities

LinkEntity intersectEntity = new LinkEntity();

intersectEntity.LinkToEntityName = “new_account_lead_custom”;

intersectEntity.LinkFromAttributeName = “leadid”;

intersectEntity.LinkToAttributeName = “leadid”;

intersectEntity.LinkEntities = new LinkEntity[] { nestedLinkEntity };

//Create Query expression and set the entity type to lead

QueryExpression expression = new QueryExpression();

expression.EntityName = “lead”;

expression.LinkEntities = new LinkEntity[] { intersectEntity };

RetrieveMultipleRequest request = new RetrieveMultipleRequest();

request.Query = expression;

//Execute and examine the response

RetrieveMultipleResponse response = (RetrieveMultipleResponse)service.Execute(request);

BusinessEntity[] entities=response.BusinessEntityCollection.BusinessEntities;

Console.WriteLine(“Total related=” + entities.Length);



Humberto Lezama

  1. December 5, 2012 at 3:06 pm

    Is it alright if I pages and use a couple of your own articles so long as I supply credit and
    resources to be able to your blog? My blog site
    is inside the same niche as yours and my users
    might genuinely really benefit from lots of the information you present here.
    Let me determine if this ok with you. Many thanks!

  2. December 28, 2012 at 2:21 pm

    Very nice post. I just stumbled upon your weblog and wanted to
    say that I have

    truly enjoyed browsing your blog posts. In any case I’ll be subscribing to your

    rss feed and I hope you write again very soon!

  3. April 13, 2013 at 9:38 am

    Whoa! This blog looks exactly like my old one! It’s on a completely

    different subject but it has pretty much the same page layout and design. Excellent choice of colors!

  4. May 3, 2013 at 1:59 am

    The next time I read a blog, I hope that it doesnt disappoint me as much as
    this one. I mean, I know it was my option to read, however I

    really thought youd have one thing fascinating to say.
    All I

    hear is a bunch of whining about one thing that you might repair should you werent too busy looking for attention.

  5. Kermit
    July 16, 2013 at 4:52 am

    When i loved ones blog page and in addition attitude. You’ll be fantastic.
    Web site in support of developing this important therefore i hope to fully grasp much more for you sometime.
    Outstanding business carrying your web sites well-defined and then fine quality without needing most unsolicited mail.

    Do you ever have much solutions to obtain by myself website to help keep this lacking in direct mail?
    And also guidelines concerning how to develop due to good high quality want your own?
    Pitiful in my everyday terms 🙂 it’s actually definitely not items indigne mouth, pray you can still perceive

  6. August 8, 2013 at 7:50 am

    Ahaa, its fastidious conversation regarding this piece of writing here at this web site, I have read all that, so at this time me also
    commenting at this place.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: