How to view plugins deployment summary ?

Sometimes we need to know when last time a plugin was updated. This information is helpful usually before exporting assemblies from one environment to other.
In similar way few times we may need to know who updated a particular assembly last time ?

The following LINQ or Fetch Xml query will return this summary:

(from p in PluginAssemblySet
orderby p.ModifiedOn descending
select new
{
PluginName = p.Name, ModifiedOn = p.ModifiedOn.Value.ToLocalTime(),
ModifiedBy= p.ModifiedBy.Name, Role=p.ModifiedBy.LogicalName,Version=p.Version
}).Dump();

 

 

Advertisements

ConditionExpression error “expected argument(s) of type ‘System.Guid’ but received ‘System.Guid[]”

Today while writing query expression I was getting error:

Condition for attribute ‘sf_contract.contractid’: expected argument(s) of type ‘System.Guid’ but received ‘System.Guid[]’.

We can pass a single or multiple values in ConditionExpression using appropriate comparison operator(s). In this example ConditionExpression was comparing multiple GUID values (stored in object array) with an attribute using “IN” comparison operator.

ConditionExpression have a few constructors, and I was trying to use one that accepts params object[] as argument but it didn’t work as per expectation.

This error was gone when I changed my collection to attribute’s base type, so basically I changed object[] to Guid[]. Hope this explanation will save someone’s time.

QueryExpression error, “The formatter threw an exception while trying to deserialize the message”

Today I wrote a QueryExpression which was throwing exception “The formatter threw an exception while trying to deserialize the message”.

The complete error message was:

“The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://schemas.microsoft.com/xrm/2011/Contracts/Services:query. The InnerException message was ‘Error in line 1 position 2016. Element ‘http://schemas.microsoft.com/2003/10/Serialization/Arrays:anyType’ contains data from a type that maps to the name ‘http://schemas.microsoft.com/xrm/2011/Contracts:EntityReference’. The deserializer has no knowledge of any type that maps to this name. Consider changing the implementation of the ResolveName method on your DataContractResolver to return a non-null value for name ‘EntityReference’ and namespace ‘http://schemas.microsoft.com/xrm/2011/Contracts’.’. Please see InnerException for more details.”

I was using ‘EntityReference’ in a condition, and error message gives hint that somehow there is an issue with ‘EntityReference’ format, and it is not being deserialized correctly. To use ‘EntityReference’ in condition we need to pass its ‘GUID’, and not complete ‘EntityReference’ object.

In the following QueryExpression, the condition will produce a similar exception which can be avoided by passing GUID instead of passing ‘EntityReference’ object as parameter.

QueryExpression query = new QueryExpression();
query.EntityName = “new_document”;
query.ColumnSet = new ColumnSet(“new_name”);
query.Criteria.AddCondition(“new_authorid”, ConditionOperator.Equal,currentDoc.GetAttributeValue<EntityReference>(“new_authorid”));
EntityCollection results =org.RetrieveMultiple(query);

#dynamics-crm, #queryexpression, #sdk, #the-formatter-threw-an-exception-while-trying-to-deserialize-the-message

The ‘orderBy’ expression is limited to invoking the ‘ ‘ parameter

LINQ is widely used in projects and it makes querying very handy. Using LINQ for querying CRM data has some limitations though, some of the standard LINQ features are not supported to use with CRM.

One such limitation is when we are joining entities and also sorting results. To use orderby, we are limited to the first entity only (the left side entity in join). So the query in Example 1 works perfectly fine:

Example 1:

var results = from c in ContactSet
join a in AccountSet
on c.ContactId equals a.PrimaryContactId.Id
orderby c.FullName
select new
{
c.FullName,
c.Address1_City,
a.Name,
a.Address1_Name
};

But trying to sort by columns of other entity is not supported. So if we try Example 2 it will throw the following NotSupportedException

The ‘orderBy’ expression is limited to invoking the ‘c’ parameter.

Exaple 2:

var results = from c in ContactSet
join a in AccountSet
on c.ContactId equals a.PrimaryContactId.Id
orderby a.Name
select new
{
c.FullName,
c.Address1_City,
a.Name,
a.Address1_Name
};

Of course if you run similar quires directly on SQL Server database they will work fine.

Solution:

If you are getting this exception there are two possible solutions:

  • Modify your quey as per Example 1 and put orderby columns’s entity firs or on the left side of join
  • For queries involving orderby from multiple entities, select data, store it in memory and use a separate LINQ query to sort it.
    This MSDN document list limitations of LINQ for CRM

Enjoy working with CRM 🙂

Parent child lookup fields in Dynamic CRM

Showing parent-child records in drop-down lists is a common requirement of business applications.

Some examples:

  1. Manager > Employees
  2. Country > State or Province > City
  3. Account category > Account sub-category > Account number

In Dynamics CRM same behaviour can be implemented by using multiple lookup fields with “Related Records Filtering” which is an out of box CRM feature. For this demo consider an entity “Car Finance Application”, which needs some related details like car brand, model and variant.

a

 

 

Steps:

  • Create the following entities and their relationship as described below:
    • Brand
    • Model, it has N:1 relationship with Brand
    • Variant, it has N:1 relationship with Model
  • Add brand, model and variant lookup fields in consumer entity which in this case is CarFinanceApplication:
  • Add brand, model and variant fields in the form
  • Double click on Model lookup field, and do the “Related Records Filtering”  configurations as shown below:  
  • Double click on Variant lookup field, and do the “Related Records Filtering”  configurations as below:

 

  • Save changes + build customizations + test working of lookup field

Form and lookup fields have been configured and selecting brand will show relevant models. As user selects a model, variant look up will list relevant records but there is a catch. If user changes brand or model after selecting variant, values in three lookup fields will not be in sync. Saving record in such scenarios will basically save  incorrect data  and you will agree many times even user will not realise this. An easy approach to fix this issue can be to reset model and variant look up fields when brand field changes and reset variant lookup field when model field changes.

  • From same form window add the following JS as a code library:
function ClearLookUp() {
for (var counter = 0; counter < arguments.length; counter++) {
if (typeof(arguments[counter]) === "string") {
var field = Xrm.Page.data.entity.attributes.get(arguments[counter]);
if (field != null && field.getValue() != null)
field.setValue(null);
}
}
}
  • Double click on “Brand” lookup field and add “ClearLookUp” javascript function on its “onChange” event. Pass execution context and name of lookup field(s) as comma-separated arguments which will need to reset.

 

  • Double click on “Model” lookup field and call “ClearLookUp” function on its “onChange” event. Pass execution context and name of lookup field(s) as a comma-separated argument.
  • That’s it, test your work and go enjoy a coffee if you like 🙂

Considerations:

  • Any number of lookup fields can be configured with this approach
  • Javascript function is a sort of generic, it can be configured with any lookup field without modification. Also just by calling once it can reset any number of lookup fields, the only requirement will be to pass the name of lookup fields as comma-separated arguments.

Credit:

Before this post, I found a similar implementation by Rashan which I have improved.

 

 

 

 

 

 

#dynamics-crm