Mapping streamlines data entry when a user creates new records that are associated with another record. When an entity has a relationship with another entity, you can create new related entity records from the associated view visible on the primary entity. When the user creates a new record from an associated view, mapped data from the primary entity record is copied to the form for the new related entity record. You control what data is copied by adding new mappings in the relationship between the two entities. If a record is created any way other than from the associated view of the primary entity, data is not mapped. Notice that if there are multiple relationships between the same pair of entities, there is only one entity map. This map will have to be used for mapping fields for both relationships.

For example, you might want to set up a mapping between the address fields in accounts and the address fields in contacts so that when a user adds a contact associated with a specific account, the address fields for the contact are filled in automatically.

You can map one attribute to multiple target attributes. For example, you can map address information in an account to both the billing and shipping addresses in an order.

Mapping only applies just before a new record is created from an associated view. A user can make changes the record is saved, and changes that are made later to the data in the primary record are not applied to the related record.

The below plug-in assembly will keep the data synchronized on subsequent updates. So now data mapping will work not only when you create the child record the first time but also whenever you update the attributes in the parent record the attributes on the child record will be updated.

Default Account Address:

clip_image002

Default related contact address

Basically the contact will inherit the parent account address due to the mapping between the account and contact entity.

This will only take effect the first time you create a contact from the account form.

clip_image002[5]

Account address updated

Account address is updated which fired the post-update plug-in

clip_image002[7]

Related contact address updated

Account post-update plug-in will update the contact address with the same value of the account address

clip_image004

Registration Information:

<Register LogFile="Plug-in Registration Log.txt" Server="http://sqlcrmsrv:5555" Org="DIC" Domain="frachkid" UserName="crmadmin">
  <Solution SourceType="1" Assembly="AccountContactAddressMapping.dll" Id="95dff72c-3f13-446e-a6e2-fec942e5f34a">
    <PluginTypes>
      <Plugin TypeName="AccountContactAddressMapping.AddressMapping" FriendlyName="0843af34-f381-45e1-974d-1fa8fd722c03" Id="9bcab9d4-9912-4bc7-a364-a1461c77a1ef">
        <Steps>
          <Step PluginTypeName="AccountContactAddressMapping.AddressMapping" PluginTypeFriendlyName="0843af34-f381-45e1-974d-1fa8fd722c03" CustomConfiguration="" SecureConfiguration="" Description="Update of account in Parent Pipeline" FilteringAttributes="" ImpersonatingUserId="" InvocationSource="0" MessageName="Update" Mode="0" PrimaryEntityName="account" SecondaryEntityName="none" Stage="50" SupportedDeployment="0" Rank="1" Id="efea63e6-f0cd-de11-864c-00155dcd1a24">
            <Images>
              <Image EntityAlias="preEntityImageXml" ImageType="0" MessagePropertyName="Target" Attributes="" Id="f9802df3-f0cd-de11-864c-00155dcd1a24" />
              <Image EntityAlias="postEntityImageXml" ImageType="1" MessagePropertyName="Target" Attributes="" Id="2040d802-f1cd-de11-864c-00155dcd1a24" />
            </Images>
          </Step>
        </Steps>
      </Plugin>
    </PluginTypes>
  </Solution>
</Register>

Source code of the plug-in assembly:

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Services.Protocols;
 
using Microsoft.Crm.Sdk;
using Microsoft.Crm.Sdk.Query;
using Microsoft.Crm.SdkTypeProxy;
 
namespace AccountContactAddressMapping
{
    //Message: Update
    //Primary Entity: Account
    //Stage: Post Stage
    //Execution Mode: Synchronous
    //Deployment: Server
    //Pipeline: Parent Pipeline
    public class AddressMapping : IPlugin
    {
        public void Execute(IPluginExecutionContext context)
        {
            try
            {
                DynamicEntity entity = null;
 
                if (context.InputParameters.Properties.Contains(ParameterName.Target)
                    && context.InputParameters.Properties[ParameterName.Target] is DynamicEntity
                    && context.MessageName.Equals("Update"))
                {
                    entity = (DynamicEntity)context.InputParameters.Properties[ParameterName.Target];
 
                    if (entity.Name.Equals("account"))
                    {
                        //Getting all the address attribute values before the update
                        DynamicEntity preEntityImage = null;
                        preEntityImage = (DynamicEntity)context.PreEntityImages.Properties["preEntityImageXml"];
                        string pre_address1_name = (string)preEntityImage.Properties["address1_name"];
                        string pre_address1_line1 = (string)preEntityImage.Properties["address1_line1"];
                        string pre_address1_line2 = (string)preEntityImage.Properties["address1_line2"];
                        string pre_address1_line3 = (string)preEntityImage.Properties["address1_line3"];
                        string pre_address1_city = (string)preEntityImage.Properties["address1_city"];
                        string pre_address1_stateorprovince = (string)preEntityImage.Properties["address1_stateorprovince"];
                        string pre_address1_postalcode = (string)preEntityImage.Properties["address1_postalcode"];
                        string pre_address1_country = (string)preEntityImage.Properties["address1_country"];
 
                        //Getting all the address attribute values after the update
                        DynamicEntity postEntityImage = null;
                        postEntityImage = (DynamicEntity)context.PostEntityImages.Properties["postEntityImageXml"];
                        string post_address1_name = (string)postEntityImage.Properties["address1_name"];
                        string post_address1_line1 = (string)postEntityImage.Properties["address1_line1"];
                        string post_address1_line2 = (string)postEntityImage.Properties["address1_line2"];
                        string post_address1_line3 = (string)postEntityImage.Properties["address1_line3"];
                        string post_address1_city = (string)postEntityImage.Properties["address1_city"];
                        string post_address1_stateorprovince = (string)postEntityImage.Properties["address1_stateorprovince"];
                        string post_address1_postalcode = (string)postEntityImage.Properties["address1_postalcode"];
                        string post_address1_country = (string)postEntityImage.Properties["address1_country"];
 
                        //Getting the account GUID
                        Key accountKey = (Key)postEntityImage.Properties["accountid"];
                        Guid accountid = accountKey.Value;
 
                        //Creating a CrmService using the plug-in context
                        ICrmService service = context.CreateCrmService(true);
 
                        //Finding all contacts that belong to ths account
                        QueryByAttribute accountContacts = new QueryByAttribute();
                        accountContacts.ColumnSet = new AllColumns();
                        accountContacts.EntityName = EntityName.contact.ToString();
                        accountContacts.Attributes = new string[] { "parentcustomerid" };
                        accountContacts.Values = new string[] { accountid.ToString() };
 
                        BusinessEntityCollection contacts = service.RetrieveMultiple(accountContacts);
 
                        //Updating contacts with the new address of the account
                        foreach (BusinessEntity b_entity in contacts.BusinessEntities)
                        {
                            contact c_contact = (contact)b_entity;
 
                            if (!post_address1_name.Equals(pre_address1_name))
                            {
                                c_contact.address1_name = post_address1_name;
                            }
                            if (!post_address1_line1.Equals(pre_address1_line1))
                            {
                                c_contact.address1_line1 = post_address1_line1;
                            }
                            if (!post_address1_line2.Equals(pre_address1_line2))
                            {
                                c_contact.address1_line2 = post_address1_line2;
                            }
                            if (!post_address1_line3.Equals(pre_address1_line3))
                            {
                                c_contact.address1_line3 = post_address1_line3;
                            }
                            if (!post_address1_city.Equals(pre_address1_city))
                            {
                                c_contact.address1_city = post_address1_city;
                            }
                            if (!post_address1_stateorprovince.Equals(pre_address1_stateorprovince))
                            {
                                c_contact.address1_stateorprovince = post_address1_stateorprovince;
                            }
                            if (!post_address1_postalcode.Equals(pre_address1_postalcode))
                            {
                                c_contact.address1_postalcode = post_address1_postalcode;
                            }
                            if (!post_address1_country.Equals(pre_address1_country))
                            {
                                c_contact.address1_country = post_address1_country;
                            }
 
                            //Executing the update method
                            service.Update(c_contact);
                        }
                    }
                }
            }
            catch (SoapException soapex)
            {
                throw new InvalidPluginExecutionException("Plugin Exception", soapex);
            }
        }
    }
}

Hope you’ll find this usefull.

Kind regards

Benjamin LECOQ (Code by Fouad Rachkidi)