You already probably knew about Expand functionality in CRM 2011 OData/REST Query. It is a useful functionality to include fields from a single related entity.
But here is a quick preview:
In the example above, I want to retrieve full name of contacts and also the subject of their originating leads.
I can further do a query on the lead subject equals ‘ab’
http://.../ContactSet?$select=FullName,contact_originating_lead/Subject&$expand=contact_originating_lead&$filter=contact_originating_lead/Subject eq 'ab'
Just as easy as 1, 2, 3.
Some caveats though:
1. You can expand on multiple relationships but beware of query performance.
http://.../ContactSet?$select=FullName,contact_originating_lead/Subject,account_primary_contact/Name,contactleads_association/Address1_PostOfficeBox&$expand=contact_originating_lead,account_primary_contact,contactleads_association&$filter=FirstName eq 'ab'
In saying that I was never able to get expanding One-To-Many relationship working, and I find expanding the Many-To-Many relationship hard to work with, so the only one that works well for me was the Many-To-One. Kinda make sense to me due to the join.
2. Filtering on multiple entity types is unsupported. This means if you are adding filter, you can only filter on a single entity type.
http://.../ContactSet?$select=FullName,contact_originating_lead/Subject&$expand=contact_originating_lead&$filter=FirstName eq 'ab' and contact_originating_lead/Subject eq 'ab'
The above is unsupported because it is filtering on contact entity and also contact_orginating_lead relationship entity.
3. Although you can expand to all types of relationships, filtering with expand works only for many-to-one relationship with the entity on query.
Cheers – Sy
Here is a little caveat to CRM 2011 customization as discovered by Iain after causing him much discomfort.
System (Built-In, Out-Of-The-Box, etc) Entities have StateCode and StatusCode.
Custom Entities have statecode and statuscode.
Note the different case between them.
Setting Filtering Attributes on Plugin Step is one of the things that is often overlooked. That is a shame because using Filtering Attributes can improve plugin performance significantly; and not to mention simplify execution order if you have complex chains of plugins.
According to MSDN article here, Filtering Attributes is
A list of entity attributes that, when changed, cause the plug-in to execute. A value of null causes the plug-in to execute if any of the attributes change.
Early Bound Code
I am very much in the favor of using early bound code as it provides compile-time checking, linq, and other perks. However, what we found out is that updating retrieved record using early bound code organisation context will bypass filtering attributes as it submits the record’s entire object graph back to CRM. CRM therefore assumes that all the attributes are being updated and thus effectively rendering filtering attributes useless.
Cheers – Sy
In this post, I’ll provide a quick code snippet to upload attachment/file via CRM 2011 annotation/note.
Inh this example I am using early-bound code generated by crmsvcutil.
var serviceContext = new GeneratedServiceContext(); //We need to create the annotation record first var annotation = new Annotation(); annotation.Subject = "Attachment Test"; annotation.ObjectId = new EntityReference("account", accountId); annotation.ObjectTypeCode = "account"; serviceContext.AddObject(annotation); //Now we get the base64 representation of the file var textContent = "Hello World!"; byte bytes = new byte[textContent.Length * sizeof(char)]; Buffer.BlockCopy(textContent.ToCharArray(), 0, bytes, 0, bytes.Length); var textContentBase64 = Convert.ToBase64String(bytes); annotation.FileName = "Plain text file"; annotation.MimeType = @"text/plain"; annotation.DocumentBody = textContentBase64; serviceContext.UpdateObject(annotation); serviceContext.SaveChanges();
Cheers – Sy
web.config style Transform is very useful. Unfortunately, it’s only available for web project. Here’s how to make it available for non-web project.
1. Unload your project
2. Edit your project file
3. Edit your config entries – note the
<ItemGroup> <Content Include="app.config" /> <Content Include="app.Debug.config"> <DependentUpon>app.config</DependentUpon> </Content> <Content Include="app.Test.config"> <DependentUpon>app.config</DependentUpon> </Content> <Content Include="app.Release.config"> <DependentUpon>app.config</DependentUpon> </Content> </ItemGroup>
4. Add transform task at the bottom of file
<Project> ... <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" /> <Target Name="AfterCompile" Condition="exists('app.$(Configuration).config')"> <!-- Generate transformed app config in the intermediate directory --> <TransformXml Source="app.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="app.$(Configuration).config" /> <!-- Force build process to use the transformed configuration file from now on. --> <ItemGroup> <AppConfigWithTargetPath Remove="app.config" /> <AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config"> <TargetPath>$(TargetFileName).config</TargetPath> </AppConfigWithTargetPath> </ItemGroup> </Target> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. <Target Name="BeforeBuild"> </Target> <Target Name="AfterBuild"> </Target> --> </Project>
5. Reload your project
On a recent project, we need to provide counts for the number of ‘targets’ for campaign. The theory in principle is simple, using plugin get all the target marketing list of a campaign and count the number of their members. For simplicity sake, only ‘static’ list is part of it. But of course the plugin must attach to an event.
First thought that comes to mind was
Associate message. And it’s wrong!!!
Turns out, if you want to add another campaign, list, product or salesliterature to a campaign, you have to use
AddItemCampaignRequest. And the corresponding message for plugin is, you guessed it
RemoveItemCampaignRequest and the corresponding message for plugin is
Check these prerequisites to have CRM 2011 Developer Toolkit functioning properly:
1. Visual Studio 2010 Professional or later
2. Microsoft Silverlight 4
3. Windows Identity Foundation
Or you may be missing this section in your solution file.
Global GlobalSection(CRMSolutionProperties) = preSolution SolutionIsBoundToCRM = TRUE EndGlobalSection EndGlobal
Courtesy of Chris Moreton.
Cheers – Sy