Thursday, November 10, 2011

context.Depth in Plugin

All,

I was facing a weird issue, when updating an entity from another entity. Let me be more clear in what I mean with an example as explained below.

Example:

  • I had registered a Plugin on Entity A


  • I had another plugin registered on Entity B


  • To meet one of the Business scenario, I was doing an Update from the Entity B on Entity A


  • There was also a workflow which was running on Entity B


  • The Issue was when updating Entity B, the execution context in Entity A was getting in to an infilite loop and was throwing up an exception.

    Inorder to overcome the above scenario, we need to make use of the context.Depth property.

    Here is how it works:
    1) The value of context.Depth property == 1 (when the plugin was initiated from an Entity A [where the plugin was registered])
    2) The value of context.Depth property == 2 (when the plugin was initiated from an Entity B and the value of Depth is 2 in the execution context of Entity A, when the update happening from an Entity B.
    3) The value of context.Depth property == 3 when the Plugin context enters Entity A from a workflow.

    To overcome the above scenario's, fallowing is the code that you need to add it in your Plugin execute method.
    if (context.Depth > 1)
     {
        return; 
     }
    

    Hope this helps,
    Chaitanya...

    Tuesday, November 8, 2011

    Retrieving all the record from an entity

    By default, the RetrieveMultiple method retrieves only 5000 records, this is a limit from the standpoint of performance. In order to retrieve more than 5000 records, please fallow the pattern explained in the below code.

    I have written a console application to retrieve all the Account records. The below code is a method to achieve that. The main logic in retrieving all the records is by passing the PageInfo object to a QueryExpression.
    private static void GetAllActiveAccounts(OrganizationServiceProxy service)
    {
    EntityCollection retrieved;
    const int servicePageSize = 5000;
    int pageNumber = 1;
    string pagingCookie = string.Empty;
    const int pageSize = servicePageSize;
    int totalRecordsCount = 0;
    
    do
    {
    var cols = new ColumnSet();
    cols.AddColumns(new string[] { ACCOUNT_ID, ACCOUNT_NAME });
    var filter = new FilterExpression { FilterOperator = LogicalOperator.And };
    filter.AddCondition(new ConditionExpression(STATE_CODE, ConditionOperator.Equal, new object[] { 0 }));
    
    
    var query = new QueryExpression
    {
    ColumnSet = cols,
    Criteria = filter,
    EntityName = ENTITY_ACCOUNT,
    PageInfo = new PagingInfo()
    {
    PageNumber = 1,
    Count = pageSize
    }
    };
    
    if (pageNumber != 1)
    {
    query.PageInfo.PageNumber = pageNumber;
    query.PageInfo.PagingCookie = pagingCookie;
    }
    
    retrieved = service.RetrieveMultiple(query);
    if (retrieved.MoreRecords)
    {
    pageNumber++;
    pagingCookie = retrieved.PagingCookie;
    }
    
    try
    {
    if (retrieved.Entities.Count > 0)
    {
    totalRecordsCount += retrieved.Entities.Count;
    
    foreach (var accountEntity in retrieved.Entities)
    {
    if (accountEntity.Attributes.Contains(ACCOUNT_ID))
    {
    var accountId = (Guid)accountEntity.Attributes[ACCOUNT_ID];
    var accountName = (string)accountEntity.Attributes[ACCOUNT_NAME];
    Console.WriteLine("Account Name: " + accountName);
    }
    }
    }
    }
    catch (Exception ex)
    {
    Console.WriteLine(ex.Message);
    Console.ReadLine();
    }
    
    } while (retrieved.MoreRecords);
    
    Console.WriteLine("Total records: " + totalRecordsCount);
    }