Quicktip: Linq query with Optionset condition

LinqPad is a great tool to quickly query CRM and export the records you want, for further processing. LinqPad Driver for Dynamics CRM is what this post is about – specifically on how to use “FormattedValues” in your queries. There are formatted values for Money, Optionset and DateTime. I will demonstrate on how to use Optionset text values in where condition.

For example this is how you can query all the open opportunities.

from q in OpportunitySet.AsEnumerable()
where q.FormattedValues["statecode"].ToLower() == "open"
select new { q.CreatedOn, q.Id, StateCodeName = q.FormattedValues["statecode"], q.StateCode }

The critical bit here is the “AsEnumerable”. If you don’t convert your set to an Enumerable, you would get this error.

image

There is a another LinqPad Driver for CRM (https://github.com/kenakamu/CRMLinqPadDriverWebAPI), but you wont be able to run similar query as WebAPI doesn’t seem to be exposing the “FormattedValues” property for each record.

Advertisements

Bug: Entity primary field & realtime workflows

When you create a new entity, one of the fields that is generally left unchanged is the primary field for the entity. It is usually “[publisherprefix]_name”.

image

This field can be either required or left optional. This value of this field, is what shows up in the entity lookups. The value of this field is usually set automatically using JavaScript, Workflow or Plugin. If the value for this field is left null, it manifests a bug in the realtime workflow.

What is the bug?

If the value of the primary field is null on a parent entity, any child entity can’t use “if condition” on the parent relationship field. It would result in a “KeyNotFound” exception.

Replication steps

  1. Create an entity that will be the parent entity
  2. Create an entity that will be the child. Create a relationship to the parent entity image
  3. Make the primary field on the parent entity as optional image
  4. Create a new realtime workflow on the child entity, with a condition statement that refers the parent lookup field in the child entity image
  5. Create a parent record without the name field setimage
  6. Create a child record that has the parent lookup set the record created in the previous step. The parent lookup will be displayed as “no name” as the primary field for the parent entity is not set.image
  7. Execute the realtime workflow against the child record in the previous step. A “The given key was not present in the dictionary” exception will be displayedimage

The issue is happening both in CRM 2015 and CRMOnline on version 8.1.0.362. This issue seems to be only affecting realtime workflows and actions, and not background workflows.

EDIT (24/06/2016): Issue logged on Connect -> https://connect.microsoft.com/site687/feedback/details/2851391/realtime-workflow-action-crash-display-name-if-condition-keynotfoundexception

Restricting the customer lookup

EDIT (04/07/2017): After testing this in 8.2.1, I have simplified the code as getLookupTypes and setLookupTypes can be used straight from the lookup itself, instead of going through getLookupDataAttribute.

First off, I have tested this only in CRMOnline on 8.1.0 and 8.2.1 so this might not work for you if you are are in older version. You can now easily restrict the default entity of the lookup, if it links to multiple types. e.g. customer lookup. The script below is for attribute of type “customer”, but you can follow a similar approach for “partylist” as well.

These new functions are undocumented, so they are technically unsupported. So, use this at your own risk. In the script below, I am restricting a field with schemaname “customerid” and of type “customer” to “contact” entity only.

JavaScript

var lookup = Xrm.Page.getAttribute('customerid');

//check if multiple type dropdowns enabled for this lookup and it is not a partylist. For partylist we might want to select an account and a contact
if (lookup.getLookupTypes().length > 1
     && !lookup.getIsPartyList()) {
    lookup.setLookupTypes(['contact']);
}

Screenshots

LookupLookup Search Customer

You can use this script during form load and easily restrict the lookup type.