Posts with tag: CRM 2011

I think most people whom use the generated service context for Microsoft CRM quickly note that it does not use the full fledged entity framework and as such does not support all queries. One of these limitations that I usually hit on is that I cant use contains in a Lambda query.

Ie. This does not work and fails with this error: Invalid 'where' condition. An entity member is invoking an invalid property or method.

private List<Xrm.Account> GetAccountsFromOrgNoList(string[] orgNos)
{
    return serviceContext.Xrm.AccountSet
        .Where(x => orgNos.Contains(x.lgc_Organizationnumber))  // <-- contains is invalid
        .Select( x=> x)
        .ToList();
}

The work around for this is to use Query Expressions. Because they can do this, although not as nicely. The below code does the same as the above code with the added exception of actually working.

private List<Xrm.Account> GetAccountsFromOrgNoList(string[] orgNos)
{
    var qe = new QueryExpression(Xrm.Account.EntityLogicalName);
    qe.ColumnSet = new ColumnSet("accountid", "name", "cst_organizationnumber"); // can use new ColumnSet(true); if you just want all columns instead of specifying specif ones
    qe.Criteria.AddCondition("cst_organizationnumber", ConditionOperator.In, orgNos.Cast<Object>().ToArray());
    qe.Distinct = true;

    var results = serviceContext.Instance.RetrieveMultiple(qe).Entities
        .Select(x => x.ToEntity<Xrm.Account>())
        .ToList();

    return results;
}

This is a piece of code I tend to need every few months but always need a few minutes to find. So I'm just going to put it on here for mine and others future reference.

The code returns a KeyValuePair list of all options in a CRM optionset.

public static List<KeyValuePair<string, int>> GetOptionSets(string entityName, string attributeName, IOrganizationService service)
{
    string AttributeName = attributeName;
    string EntityLogicalName = entityName;
    RetrieveEntityRequest retrieveDetails = new RetrieveEntityRequest
    {
        EntityFilters = EntityFilters.All,
        LogicalName = EntityLogicalName
    };
    RetrieveEntityResponse retrieveEntityResponseObj = (RetrieveEntityResponse)service.Execute(retrieveDetails);
    Microsoft.Xrm.Sdk.Metadata.EntityMetadata metadata = retrieveEntityResponseObj.EntityMetadata;
    Microsoft.Xrm.Sdk.Metadata.PicklistAttributeMetadata picklistMetadata = metadata.Attributes.FirstOrDefault(attribute => String.Equals(attribute.LogicalName, attributeName, StringComparison.OrdinalIgnoreCase)) as Microsoft.Xrm.Sdk.Metadata.PicklistAttributeMetadata;
    Microsoft.Xrm.Sdk.Metadata.OptionSetMetadata options = picklistMetadata.OptionSet;
    var ret = options.Options
        .Where(x => x.Label != null && x.Label.UserLocalizedLabel != null && x.Label.UserLocalizedLabel.Label != null && x.Value.HasValue)
        .Select(x => new KeyValuePair<string, int>(x.Label.UserLocalizedLabel.Label, x.Value.Value))
        .ToList();

    return ret;
}

To use it call it as such:

GetOptionSets(Account.EntityLogicalName, "cst_sttributeWithOptionset", serviceContext.Instance);