Wednesday, May 25, 2016

How to: Initialize Objects by Using an Object Initializer

 The following code consolidates examples from the topic.
class ObjInitializers
{
    class Cat
    {
        // Auto-implemented properties.
        public int Age { get; set; }
        public string Name { get; set; }
    }

    static void Main()
    {
        Cat cat = new Cat { Age = 10, Name = "Fluffy" };

        List<Cat> cats = new List<Cat>
        {
            new Cat(){ Name = "Sylvester", Age=8 },
            new Cat(){ Name = "Whiskers", Age=2 },
            new Cat(){ Name = "Sasha", Age=14 }
        };

        List<Cat> moreCats = new List<Cat>
        {
            new Cat(){ Name = "Furrytail", Age=5 },
            new Cat(){ Name = "Peaches", Age=4 },
            null
        };

        // Display results.
        System.Console.WriteLine(cat.Name);

        foreach (Cat c in cats)
            System.Console.WriteLine(c.Name);

        foreach (Cat c in moreCats)
            if (c != null)
                System.Console.WriteLine(c.Name);
            else
                System.Console.WriteLine("List element has null value.");
    }
    // Output:
    //Fluffy
    //Sylvester
    //Whiskers
    //Sasha
    //Furrytail
    //Peaches
    //List element has null value.
}

Reference-
https://msdn.microsoft.com/en-us/library/bb397680.aspx

Multiple conditions for a FilterExpression in CRM 2015

(A_logicalName AND B_LogicalName) OR (B_LogicalName AND C_LogicalName)





FilterExpression filter = new FilterExpression(LogicalOperator.Or);

FilterExpression filter1 = new FilterExpression(LogicalOperator.And);
filter1.Conditions.Add(new ConditionExpression("A_LogicalName", ConditionOperator.Equal, id1));
filter1.Conditions.Add(new ConditionExpression("B_LogicalName", ConditionOperator.Equal, id2));

FilterExpression filter2 = new FilterExpression(LogicalOperator.And);
filter2.Conditions.Add(new ConditionExpression("B_LogicalName", ConditionOperator.Equal, id2));
filter2.Conditions.Add(new ConditionExpression("C_LogicalName", ConditionOperator.Equal, id3));

filter.AddFilter(filter1);
filter.AddFilter(filter2);

query.Criteria = filter;





Criteria = new FilterExpression
{
  FilterOperator = LogicalOperator.Or,
  Filters =
  {
    new FilterExpression
    {
      FilterOperator = LogicalOperator.And,
      Conditions =
      {
        new ConditionExpression("field1", ConditionOperator.NotNull),
        new ConditionExpression("field2", ConditionOperator.NotNull)
      }
    },
    new FilterExpression
    {
      FilterOperator = LogicalOperator.And,
      Conditions =
      {
        new ConditionExpression("field3", ConditionOperator.NotNull),
        new ConditionExpression("field4", ConditionOperator.NotNull)
      }
    }
  }
}
...




Reference -

http://stackoverflow.com/questions/14318160/multiple-conditions-for-a-filterexpression
https://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.query.queryexpression.aspx


OrganizationServiceProxy vs. OrganizationService

What is the difference between OrganizationServiceProxy and OrganizationService, and why/when would I prefer one over the other when working with Entities?


Answer-
If you're using the sdk assemblies (specifically microsoft.xrm.sdk.dll), then you'll be using an implementation of IOrganizationService, and the call time will be identical. The main purpose of OrganizationServiceProxy is to provide options for establishing a connection to CRM in code that runs outside of CRM - this is in contrast to plugins, for example

Reference -


https://social.technet.microsoft.com/Forums/en-US/19fb9e42-1502-4dec-860a-733cc45e33ae/organizationserviceproxy-vs-organizationservice?forum=crmdevelopment

Retrieve task 2 days after and before today's date using Query expression in CRM 2015

  QueryExpression queryExp = new QueryExpression();
                queryExp.EntityName = "task";
                queryExp.ColumnSet = new ColumnSet();
                queryExp.ColumnSet.AddColumns("activityid", "statecode", "scheduledend", "aces_notificationdate");

                ConditionExpression condition1 = new ConditionExpression();
                condition1.AttributeName = "scheduledend";
                condition1.Operator = ConditionOperator.On;
                condition1.Values.Add(DateTime.UtcNow.AddDays(2));
          
                ConditionExpression condition2 = new ConditionExpression();
                condition2.AttributeName = "statecode";
                condition2.Values.Add(0);//condition to retrieve cases associated with Master Case

                ConditionExpression condition3 = new ConditionExpression();
                condition3.AttributeName = "scheduledend";
                condition3.Operator = ConditionOperator.On;
                condition3.Values.Add(DateTime.UtcNow.AddDays(-2));
           
                    //FilterExpression filterExpression = new FilterExpression();
                    //filterExpression.AddCondition(condition1);
                    //filterExpression.AddCondition(condition2);
                    //filterExpression.AddCondition(condition3);
                    //filterExpression.FilterOperator = LogicalOperator.And;


            FilterExpression filterExpression = new FilterExpression();
            FilterExpression filterExpression1 = new FilterExpression();
            FilterExpression filterExpression2 = new FilterExpression();

            filterExpression1.AddCondition(condition1);
            filterExpression1.AddCondition(condition2);

            filterExpression2.AddCondition(condition2);
            filterExpression2.AddCondition(condition3);

            filterExpression.FilterOperator = LogicalOperator.Or;
            filterExpression1.FilterOperator = LogicalOperator.And;
            filterExpression2.FilterOperator = LogicalOperator.And;
            filterExpression.AddFilter(filterExpression1);
            filterExpression.AddFilter(filterExpression2);





            queryExp.Criteria = filterExpression;

Monday, May 23, 2016

CRM 2015 Quick connection with a sample

 static void Main(string[] args)
        {
         
            Microsoft.Xrm.Client.CrmConnection connection = CrmConnection.Parse(@"Url=http://xxxxxx/CRM2015Test/; Username= ; Password= ;");

           
            Console.WriteLine("Connecting...");

           
           
            // Obtain an organization service proxy.
            // The using statement assures that the service proxy will be properly disposed.
            using (var _orgService = new OrganizationService(connection))
            {
               WhoAmIResponse resp = (WhoAmIResponse)_orgService.Execute(new WhoAmIRequest());
                Console.WriteLine("My UserID is: " + resp.UserId.ToString());
                Console.Write("DONE!!");
                Console.ReadKey();


                string strFetchXML = @"<fetch>
                             <entity name='account' >
                               <attribute name='name' />
                                   <link-entity name='principalobjectaccess' from='objectid' to='accountid' link-type='inner' alias='poa' >
                                      <attribute name='objectid' alias='objectid' />
                             
                                      <link-entity name='team' from='teamid' to='principalid' link-type='inner' >
                                        <link-entity name='teamtemplate' from='teamtemplateid' to='teamtemplateid' >
                                          <attribute name='teamtemplatename' />
                                        </link-entity>
                                        <link-entity name='teammembership' from='teamid' to='teamid' link-type='inner' intersect='true' >
                                          <link-entity name='systemuser' from='systemuserid' to='systemuserid' link-type='inner' >
                                            <attribute name='fullname' />
                                         </link-entity>
                                       </link-entity>
                                      </link-entity>
                              </link-entity>
                                     <filter type='and'>
                                       <condition attribute='name' operator='eq' value='China' />
                                        </filter>  

                                  </entity>
                                </fetch>";

                EntityCollection entColAccessTeamMembers = _orgService.RetrieveMultiple(new FetchExpression(strFetchXML));



           

            }  
           
        }

Import/Export and Publish CRM Solutions programmatically in CRM 2015

 IMport/Export and Publish CRM Solutions programmatically



  private static void ExportCRMSolutions(bool managed = false)
        {

            if (ConfigurationHelper.CrmSolutions.Count() > 0)
            {
                Console.WriteLine(string.Format("{0} Exporting {1} Solution(s)", MESSAGE_PREFIX, ConfigurationHelper.CrmSolutions.Count().ToString()));

                foreach (string solution in ConfigurationHelper.CrmSolutions)
                {
                    // Retrieve version number for file name
                    QueryExpression querySolution = new QueryExpression
                    {
                        EntityName = "solution",
                        ColumnSet = new ColumnSet(new string[] { "version", "versionnumber" }),
                        Criteria = new FilterExpression()
                    };

                    querySolution.Criteria.AddCondition("uniquename", ConditionOperator.Equal, solution);
                    EntityCollection matchingSolutions = ServiceProxy_Origin.RetrieveMultiple(querySolution);

                    string version = matchingSolutions.Entities[0].Attributes["version"].ToString();
                    version = version.Replace('.', '_');

                    // Set Exported solution file name
                    string filename;
                    if (managed)
                    {
                        filename = solution + "_" + version + "_managed.zip";
                    }
                    else
                    {
                        filename = solution + "_" + version + ".zip";
                    }

                    if (managed)
                        Console.WriteLine(string.Format("{0} Exporting Managed Solution '{1}' from CRM Organization {2}", MESSAGE_PREFIX, solution, ConfigurationHelper.CrmSourceOrganization));
                    else
                        Console.WriteLine(string.Format("{0} Exporting Unmanaged Solution '{1}' from CRM Organization {2}", MESSAGE_PREFIX, solution, ConfigurationHelper.CrmSourceOrganization));

                    // Export Solution Request
                    ExportSolutionRequest exportRequest = new ExportSolutionRequest
                    {
                        Managed = managed,
                        SolutionName = solution
                    };
                    ExportSolutionResponse exportResponse = ServiceProxy_Origin.Execute(exportRequest) as ExportSolutionResponse;

                    // Write to disk
                    File.WriteAllBytes(ConfigurationHelper.CrmSolutionsDirectory + filename, exportResponse.ExportSolutionFile);

                    Console.WriteLine(string.Format("{0} Solution '{1}' Saved to disk as '{2}'", MESSAGE_PREFIX, solution, filename));
                }
            }
        }

        /// <summary>
        /// Import CRM solutions in target organization
        /// Note : uses the most recently modified UMANAGED solution in the target folder
        /// (no solution number comparison and no import of managed solutions either)
        /// </summary>
        /// <param name="publishAfterImport"></param>
        private static void ImportCRMSolutions(bool publishAfterImport = false)
        {
            if (ConfigurationHelper.CrmSolutions.Count() > 0)
            {
                Console.WriteLine(string.Format("{0} Importing {1} Solution(s)", MESSAGE_PREFIX, ConfigurationHelper.CrmSolutions.Count().ToString()));

                List<string> solutionFilesToImport = new List<string>();

                foreach (string solution in ConfigurationHelper.CrmSolutions)
                {
                    // get list of filenames matching our solution name
                    string[] dirs = Directory.GetFiles(ConfigurationHelper.CrmSolutionsDirectory, solution + "_*.zip");
                    SortedSet<FilenameDate> possibleCandidates = new SortedSet<FilenameDate>(new byDate());
                    foreach (string f in dirs)
                    { // retrieve their modified dates and sort by these
                        FileInfo d = new FileInfo(f);
                        possibleCandidates.Add(new FilenameDate { filename = f, modifiedDate = d.LastWriteTime });
                    }
                    IEnumerator<FilenameDate> candidates = possibleCandidates.Reverse().GetEnumerator();
                    while (candidates.MoveNext() != false)
                    {   // take the newest file, excluding managed solutions
                        if (!candidates.Current.filename.Contains("managed.zip"))
                        {
                            solutionFilesToImport.Add(candidates.Current.filename);
                            break;
                        }
                    }
                }

                foreach (string file in solutionFilesToImport)
                {
                    Console.WriteLine(string.Format("{0} Importing Solution at '{1}' to CRM Organization {2}", MESSAGE_PREFIX, file, ConfigurationHelper.CrmTargetOrganization));

                    ImportSolutionRequest importSolution = new ImportSolutionRequest
                    {
                        OverwriteUnmanagedCustomizations = true,
                        CustomizationFile = File.ReadAllBytes(file),
                        PublishWorkflows = true,
                        ImportJobId = Guid.NewGuid()
                    };

                    try
                    {
                        ImportSolutionResponse importResponse = ServiceProxy_Target.Execute(importSolution) as ImportSolutionResponse;
                    }
                    catch (Exception e)
                    {
                        if (!e.Message.StartsWith("The request channel timed out while waiting for a reply after "))
                        {
                            throw e; // if timed out, ignore exception, otherwise throw
                        }
                    }

                    String SolutionImportResult = null;
                    String PercentDone = null;
                    double percent = 0.0;
                    do
                    {

                        try
                        {
                            Entity job = ServiceProxy_Target.Retrieve("importjob", importSolution.ImportJobId, new
                            ColumnSet(new System.String[] { "data", "solutionname" }));

                            System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
                            doc.LoadXml(job["data"].ToString());
                            PercentDone = doc.SelectSingleNode("importexportxml/@progress").Value;
                            SolutionImportResult = doc.SelectSingleNode("//solutionManifest/result/@result").Value;
                            percent = Double.Parse(PercentDone);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message);
                        }

                        if (percent < 100)
                        {
                            Console.WriteLine("    Import is {0}% complete.", percent);
                            System.Threading.Thread.Sleep(10000);
                        }

                    } while (percent < 100 && SolutionImportResult.CompareTo("success") == 0);

                    Console.WriteLine("{0} Solution Import Result: {1}", MESSAGE_PREFIX, SolutionImportResult.ToUpper());
                }

                if (publishAfterImport)
                    PublishAllCustomizations();
            }
        }

        /// <summary>
        /// Publish all customizations in Target environment
        /// </summary>
        /// <returns></returns>
        private static PublishAllXmlResponse PublishAllCustomizations()
        {
            PublishAllXmlResponse response = null;
            PublishAllXmlRequest req = new PublishAllXmlRequest();
            req.RequestId = Guid.NewGuid();

            Console.WriteLine(string.Format("{0} Publishing all customizations for organization {1}. Please wait...", MESSAGE_PREFIX, ConfigurationHelper.CrmTargetOrganization));
            try
            {
                response = ServiceProxy_Target.Execute(req) as PublishAllXmlResponse;
            }
            catch (Exception e)
            {
                if (!e.Message.StartsWith("The request channel timed out while waiting for a reply after "))
                {
                    throw e; // if timed out, ignore exception
                }
                else
                {
                    Console.WriteLine("Publishing all customizations has not yet completed (the service request timed out).");
                }
            }

            Console.WriteLine(string.Format("{0} Publishing all customizations *** Success ***", MESSAGE_PREFIX));

            return response;
        }



Friday, May 20, 2016

{Tips & Tricks} How to optimize your report query in Dynamics CRM minimizing the use of filtered views

{Tips & Tricks} How to optimize your report query in Dynamics CRM minimizing the use of filtered views

Reference -

https://debajmecrm.com/2015/08/28/tips-tricks-how-to-optimize-your-report-query-in-dynamics-crm-minimizing-the-use-of-filtered-views/

There are many topics on optimizing the performance of the reports in Dynamics CRM. And it has been discussed so many times about the performance of filtered views. However no matter how much we try, we have to use filtered views for the security context of the report.

And here I was called for to optimize the performance of another such report which uses filtered views. The report was constantly timing out. The report was basically a join of the FilteredOpportunity with around 10 master data entities and around 5 filter operators. And the total opportunities in the system were around 1,50,000.

So I had to optimize the report for the maximum possible records to be returned. I have to use filtered opportunity view but how do I minimize the performance effect of it. And while I was thinking, suddenly a trick came to my mind.

First I ran the query

Select * from FilteredOpportunity

The query completed in 2 minutes and 35 seconds. Then I ran the below query.

DECLARE @OPPS TABLE
(
    ID UNIQUEIDENTIFIER
)

INSERT INTO @OPPS
SELECT DISTINCT OpportunityId From FilteredOpportunity

SELECT *
FROM Opportunity O INNER JOIN @OPPS OP
ON O.OpportunityId = OP.ID


And voila!. The query returned the results in just 8 seconds. The reason is because the primary key column of a table is clustered index and the fetch on just the primary key would be very fast compared to the fetch of the other columns from the view.



I replaced FilteredOpportunity with the Opportunity entity view. And joined the Opportunity with the @OPPS table on the opportunityid column. Off course to retrieve the names text values of the option set and all, I had to join with the String Map table but after I constructed the query and ran the report, it consistently executed within 30 seconds even with the maximum set of data.



Hope this helps when you face the same problem while you develop SSRS reports in Dynamics CRM.
Posted on August 28, 2015