Wednesday 25 May 2011

Unexpected error with ConditionOperator.In and typed arrays

I just met a bizarre error when using the Crm xrm assembly when using the ConditionOperator.In in a query. In this case the query was to find all notes related to a list of CRM entities, and the error was "Condition for attribute 'annotation.objectid': expected argument(s) of type 'System.Guid' but received 'System.Guid[]'". I was using almost identical code to some code that did work, but there was a subtle difference in the overloads of some of the xrm methods.

Consider the following code, which works:

QueryExpression q = new QueryExpression("annotation");
Guid g1 = Guid.NewGuid();
Guid g2 = Guid.NewGuid();
q.Criteria.AddCondition(new ConditionExpression("objectid", ConditionOperator.In, new Guid[] { g1, g2 }));

However, change the last line to the following, and it fails with the error above:

q.Criteria.AddCondition("objectid", ConditionOperator.In, new Guid[] { g1, g2 });

On the face of it, you'd expect identical behaviour, but it looks like the problem is due to the parameter overloads on the different methods. The constructor for ConditionExpression takes 5 overloads, and the compiler will use System.Collections.ICollection for the array of Guids. However, the AddCondition method only offers one type for the third parameter (params object[]). The result of this is that the code fails because the parameter is interpreted as object[] {new Guid[] { g1, g2 }}.

Interestingly, other code can also work, e.g.

q.Criteria.AddCondition("objectid", ConditionOperator.In, new object[] { g1, g2 });
q.Criteria.AddCondition("objectid", ConditionOperator.In, g1, g2);