private static bool EntityAttributesEqual(IExecutionContainer container, List <string> matchattributes, Entity entity1, Entity entity2)
        {
            var match = true;

            foreach (var attr in matchattributes)
            {
                var srcvalue = "";
                if (attr == container.Entity(entity1.LogicalName).PrimaryIdAttribute)
                {
                    srcvalue = entity1.Id.ToString();
                }
                else
                {
                    srcvalue = container.AttributeAsBaseType(entity1, attr, "<null>", true).ToString();
                }
                var trgvalue = container.AttributeAsBaseType(entity2, attr, "<null>", true).ToString();
                if (srcvalue != trgvalue)
                {
                    match = false;
                    break;
                }
            }
            return(match);
        }
        private EntityCollection GetMatchingRecords(IExecutionContainer container, Entity cdEntity, List <string> matchattributes, List <string> updateattributes, bool preretrieveall, ref EntityCollection cAllRecordsToMatch)
        {
            container.StartSection(MethodBase.GetCurrentMethod().Name);
            EntityCollection matches = null;
            var allattributes        = new List <string>
            {
                container.Entity(cdEntity.LogicalName).PrimaryIdAttribute
            };

            if (cdEntity.Contains("ownerid"))
            {
                allattributes.Add("ownerid");
            }
            if (cdEntity.Contains("statecode") || cdEntity.Contains("statuscode"))
            {
                allattributes.Add("statecode");
                allattributes.Add("statuscode");
            }
            allattributes = allattributes.Union(matchattributes.Union(updateattributes)).ToList();
            if (preretrieveall)
            {
                if (cAllRecordsToMatch == null)
                {
                    cAllRecordsToMatch = GetAllRecordsForMatching(container, allattributes, cdEntity);
                }
                matches = GetMatchingRecordsFromPreRetrieved(container, matchattributes, cdEntity, cAllRecordsToMatch);
            }
            else
            {
                var qMatch = new QueryExpression(cdEntity.LogicalName)
                {
                    // We need to be able to see if any attributes have changed, so lets make sure matching records have all the attributes that will be updated
                    ColumnSet = new ColumnSet(allattributes.ToArray())
                };

                foreach (var matchattr in matchattributes)
                {
                    object value = null;
                    if (cdEntity.Contains(matchattr))
                    {
                        value = container.AttributeAsBaseType(cdEntity, matchattr, null, false);
                    }
                    else if (matchattr == container.Entity(cdEntity.LogicalName).PrimaryIdAttribute)
                    {
                        value = cdEntity.Id;
                    }
                    if (value != null)
                    {
                        Query.AppendCondition(qMatch.Criteria, LogicalOperator.And, matchattr, Microsoft.Xrm.Sdk.Query.ConditionOperator.Equal, value);
                    }
                    else
                    {
                        Query.AppendCondition(qMatch.Criteria, LogicalOperator.And, matchattr, Microsoft.Xrm.Sdk.Query.ConditionOperator.Null, null);
                    }
                }
#if DEBUG
                container.Log($"Finding matches for {cdEntity.LogicalName}:\n{container.ConvertToFetchXml(qMatch)}");
#endif
                matches = container.RetrieveMultiple(qMatch);
            }
            container.EndSection();
            return(matches);
        }