FetchXML count="-1" now returns records again

Last September I highlighted a change in the FetchXML interpretation, where using syntax like…

<fetch count="-1" mapping="logical" version="1.0">
  <entity name="account">
    <attribute name="name" />
    <attribute name="address1_city" />
  </entity>
</fetch>

…would not return any records. You had to use a count of “0” instead.
Now, when running CRM 2013, a count of “-1” returns records again 🙂
Perhaps someone in the product team happened to read my post and thought they should be nice to me.
That was kind.

MS CRM 2011 UR14 Breaking Change: FetchXML count="-1" does not return any records

A change in the interpretation of FetchXML “count” attribute has been identified from Update Rollup 14 for Microsoft Dynamics CRM 2011.

In many situations when you use FetchXML you have the need to return all records available, instead of using paging or in other ways limiting the number of records returned.
Up until now, we have regularly used the method of setting the count attribute to “-1” to indicate “all records”.

<fetch count="-1" mapping="logical" version="1.0">
  <entity name="account">
    <attribute name="name" />
    <attribute name="address1_city" />
  </entity>
</fetch>

This is however not a good idea if you are running CRM with UR 14. Instead, this will not return any records at all!
Setting the count attribute to “0” or completely omitting the count attribute will return all records (up to the internally set limit, typically 5000).

<fetch count="0" mapping="logical" version="1.0">
  <entity name="account">
    <attribute name="name" />
    <attribute name="address1_city" />
  </entity>
</fetch>

In the documentation of the FetchXML syntax it is not stated how to use the count attribute to instruct CRM to return all records, and maybe it is just us who ignorantly have used the “-1” value until now and just us who consider the change to be “breaking”… but somehow, I don’t really think so.

Are You a Rock Star?

rockstar The Microsoft Dynamics CRM community is constantly growing, and it does so in many directions. Now we are all (who desire to sign up for it) ranked by our individual CRM Rock Star shine! Just enter your certs, projects and inspirations and – voila! – you get your ranking in your own country and globally. rockstarJR Check my stats here http://crmrockstar.com/rappen and sign up to find out how much of a Rock Star you are!

MS CRM SDK 5.0.13: Xrm.Page.context.getClientUrl – at last!

The long long wait is over… Have you ever had a CRM installation that can be accessed using different URLs, e.g. one to be used inside a corporate network, and one to be used for external access?
Have you also written some javascript to make calls to the OData endpoint or to open a new entity form? Then you have realized that the context.getServerUrl method returns the URL that was assigned the server during the installation of CRM, and not the URL currently used to access CRM. Why is that a problem? Well, authenticating the user to one URL, and then having javascript making calls to the OData endpoint on another URL, will just give the user a “too bad, you are not authorized to do anything on this URL”. Now, at last, in Microsoft Dynamics CRM Software Development Kit version 5.0.13 the context.getClientUrl method is introduced, which returns the base URL currently used by the user to access the CRM application.
The getServerUrl method is still there, but deprecated and should not be used in the future. Documentation can be found here. Happy javascripting!

CRM 2011: Multiple Cascade Delete – part 2

In my previous post CRM 2011: Multiple Cascade Delete – part 1 I discussed the limitations in relationship behavior configuration for manual intersect entities, and proposed a solution with a plugin and a configuration entity.

In this post I will go into the details of the plugin and how it is registered.

I will not go into the basics of writing a plugin, there are tons of examples out there.
You need to be somewhat familiar with the event execution pipeline in Microsoft Dynamics CRM 2011 and the SDK classes used when developing plugins using late binding.

Objective

Consider the following entity model:

AccountContact2

Role records should be deleted if either the associated contact or account is deleted, but only one of the relations can be configured with cascade delete. Responsibility records should be deleted if associated Role is deleted. The goal is to accomplish this through a generic plugin that is configured using a dedicated CRM entity.

Plugin overview

The plugin will contain three main blocks

  1. Configuration cache being loaded on demand and cleared whenever a Cascade Delete rule is being changed.
  2. Pre Validation step to retrieve all child records that should be deleted prior to the parent record being deleted.
  3. Pre Operation step to perform the deletion of retrieved child records.

The reason for separating block 2 and 3 is described in more detail in the previous post.

Continue reading “CRM 2011: Multiple Cascade Delete – part 2”

CRM 2011: Multiple Cascade Delete – part 1

As I have recently mentioned, the possibilities of defining cascade deletes in Microsoft Dynamics CRM 2011 are quite limited. Only one parent entity can have the relationship behavior set to Cascade Delete. When you create a manual intersect entity to connect two or more other entities, this constraint is simply not acceptable for the end users.

Scenario

Consider this classic scenario: Instead of just associating contacts with a parent account, you want to be able to define a more dynamic model.AccountContactThis could be accomplished using Connections and Connection Roles, but that too has a number of pros and cons, which I will not go into in this article. When creating the relations to the Role entity, only one of them (i.e. either the relation to Account, Contact or Function) can be defined with cascade delete. What you would like here is to specify Cascade for both Account and Contact, and Remove Link for Function.

When using a manual intersect entity as in this example, the Role object will loose all meaning if either the associated Contact or the associated Account is deleted, thus the Role should of course be deleted in both cases.

To solve this, I will create a plugin which can be configured to perform the cascade behavior where it is not possible to do it by customizations only.

Relationship Behavior

First a few notes about the different types of relationship behavior during delete. The Restrict behavior verifies if there are any existing associating records before stage 20 (Pre Operation). So this behavior cannot be used, as we want to perform our configured plugin delete within the triggering transaction to ensure proper rollback behavior. The Cascade behavior can only be defined for one relationship, which in this case will be to the Contact entity. The Remove Link behavior will leave the child records in CRM, which is possible as the relationship attribute will be nulled by CRM between stage 10 and 20. Using this behavior alone would leave Roles defining e.g. that “Jonas has function Consultant at company null” when deleting accounts.

Objective and Configuration

A plugin shall delete children of a parent record that is being deleted. To specify which relationships that shall invoke this function, I use a configuration entity in CRM.CascadeDeleteDefinition3 It is also possible to pass the configuration as parameters to the plugin constructor, but then you have to enter the configuration in the step registrations, which is not very user friendly to the sysadmin. The operation shall be performed in stage 20 (Pre Operation) as it will then be within the transaction of the triggering delete, and the children will be deleted before the parent record is actually removed from the database. As the lookup attributes are nulled before stage 20 of the event execution pipeline, the plugin will retrieve a list of the children to delete in stage 10. This list is passed to the plugin triggered in stage 20 within the context’s SharedVariables. To improve performance, a cache of Cascade Delete configurations is maintained in the plugin class. If a configuration record is created, updated or deleted, the cache will be cleared.

In the next post I demonstrate and explain the code in the plugin, and also provide a complete solution for deploying multiple cascade delete in your Microsoft Dynamics CRM. Stay tuned!