How to create Proxy Classes

CRM Solution Manager now provides the ability to generate lightweight, smart, proxy classes that give you the intellisense you want without the overhead of using crmsvcutil. These classes include the ability to track changes made to each object. In this manner you are able to update only those properties that have actually changed instead of pushing the entire object to CRM. This helps remove clutter from the audit logs that track everything that is pushed on an updated object instead of just logging those values that have actually changed.

To generate one more proxy classe simply open up the 'CRM Solution Manager Explorer' by going to the 'View' -> 'Other Windows' sub menu in Visual Studio and select the 'CRM Solution Manager Explorer' menu:

CRM Solution Manager Explorer Menu

This will open up a toolbox window which can be docked like any other window in Visual Studio:

CRM Solution Manager Explorer Window

If there is nothing listed then you'll need to log into your CRM organization first and then press the 'Refresh' button.

Simply select each of the entities that you would like to generate a proxy class for and then press the 'Create Proxy Class' near the top.

This will open up another dialog which will allow you to change where and how the proxy classes will be generated.

Proxy Class Settings

You can select which project you would like to generate proxy classes for as well as the namespace and how you would like the class and properties to be named. Based on the project language, whether C# or VB.Net, proxy classes will be generated for you in the same language.

After pressing the 'OK' button, your proxy classes will now be generated and placed in a folder called 'ProxyClasses' in the specified project.

Proxy Classes Generated in Folder

Take note that in addition to the selected entities, there will be a 'BaseProxyClass' from which all proxy classes will inherit from.

Once your classes have been generated they are now ready to use.

You'll want to take note that all money properties have now been converted to a 'decimal' type for easier modification. All Option sets have also been converted to enum types with all the appropriate values.

Take for example the 'Account' entity: You can now simply specify the 'Address1' type like this:

Account Address Type Enum

If you still need access to either the 'Money' value or 'OptionSetValue', you can still access those directly as well. They simply have 'Money' or 'OptionSetValue' appended to their property names:

OptionSetValue Property

Several methods have been added to each proxy class to make it easy to create, update, delete or set the state of an object.

            //Create a new account and set some properties
            Account Account = new Account();
            Account.Address1_Street1 = "1234 Some Street";
            Account.Address1_City = "Some City";
            Account.Address1_ZIP_PostalCode = "95663";
            Account.Address1_State_Province = "CA";
            Account.Address1_AddressType = Account.eAddress1_AddressType.BillTo;
            //Or alternately

            //Update the street address
            Account.Address1_Street1 = "4321 Some Street";

            //Since this is a smart object, when calling the 'Update' method
            //only the address will be sent to CRM, not the entire object again.
            //Or Alternately

            //Set the state of the account
            Account.SetState(Service, Account.eStatus.Inactive, Account.eStatusReason.Inactive);
            //Or Alternately
            Service.SetState(Account, Account.StatusOptionSetValue, Account.StatusReasonOptionSetValue);
            //Retrieve any related contacts
            List<Contact> RelatedContacts = Account.GetContacts(Service).ToProxies<Contact>();

            //Relate a Lead to the Many to Many Relationship
            Account.RelateLeads(Service, new EntityReference("lead", new Guid("{A7114540-7656-428F-AB9E-74A5E71BE091}")));
            //Un-relate a Lead from the Many to Many Relationship
            Account.UnRelateLeads(Service, new EntityReference("lead", new Guid("{A7114540-7656-428F-AB9E-74A5E71BE091}")));

            //Delete the account
            //Or Alternately

There are also several extension methods that can be used when working with the IOrganizationService and regular Entity objects.

            //Retrieve an Account proxy entity based on a GUID
            Account Account = Service.RetrieveProxy<Account>
                new Guid("02215050-6890-453B-9B7A-7F54B54B81D0"),
                new Microsoft.Xrm.Sdk.Query.ColumnSet(true));

            //Retreive the parent account entity with only the 'Account Name' and 'Account Number' properties
            //Notice that there is a static class called 'Properties' with all the propery names defined as constants
            //for easy retrieval of specific attributes.
            Account ParentAccount = Account.ParentAccount.RetrieveProxy<Account>(

            //Retrieve all the children accounts
            ConditionExpression ChildAccountCondition = new ConditionExpression(

            //Specify only to retrieve the account name of each child account
            List<Account> ChildAccounts = Service.RetrieveProxies<Account>(
                new ColumnSet(Account.Properties.AccountName));

            //Or alternately
            EntityCollection ChildAccounCollection = Service.RetrieveMultiple(Query);
            ChildAccounts = ChildAccounCollection.ToProxies<Account>();

You can also use the standard 'Entity' class interchangeably with the Proxy classes:

            //Retrieve a standard entity object
            Entity AccountEntity = Service.Retrieve(
                new Guid("02215050-6890-453B-9B7A-7F54B54B81D0"), 
                new ColumnSet(true));

            //Create a new proxy object with the current entity object
            Account AccountProxy = new Account(AccountEntity);

            //Use any of the proxy properties to get or set values
            AccountProxy.Address1_ShippingMethod = Account.eAddress1_ShippingMethod.Airborne;

            //Use the standard way of updating using the 'Entity' object
            //The 'Entity' object is simply the property 'Entity' on each proxy class
            AccountEntity = AccountProxy.Entity;