private static void Associate(CrmDbContext context, ContentMap map, EntityReference target, Relationship relationship, EntityReferenceCollection relatedEntities)
        {
            target.ThrowOnNull("target");
            relationship.ThrowOnNull("relationship");
            relatedEntities.ThrowOnNull("relatedEntities");

            ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Target: LogicalName={0}, Id={1}", EntityNamePrivacy.GetEntityName(target.LogicalName), target.Id));
            ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Relationship: SchemaName={0}, PrimaryEntityRole={1}", relationship.SchemaName, relationship.PrimaryEntityRole));

            foreach (var entity in relatedEntities)
            {
                ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Related: LogicalName={0}, Id={1}", EntityNamePrivacy.GetEntityName(entity.LogicalName), entity.Id));
            }

            // validate that the relationships do in fact exist by querying for the intersects

            var entities = map.Using(ContentMapLockType.Read, () => RetrieveIntersectEntities(context, map, target, relationship, relatedEntities));

            if (entities != null)
            {
                // add intersect entities to the content map

                map.Using(ContentMapLockType.Write, () => map.AddRange(entities));

                foreach (var added in entities)
                {
                    ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Added: LogicalName={0}, Id={1}", EntityNamePrivacy.GetEntityName(added.LogicalName), added.Id));
                }
            }
        }
        private void Disassociate(CrmDbContext context, ContentMap map, EntityReference target, Relationship relationship, EntityReferenceCollection relatedEntities)
        {
            target.ThrowOnNull("target");
            relationship.ThrowOnNull("relationship");
            relatedEntities.ThrowOnNull("relatedEntities");

            ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Target: LogicalName={0}, Id={1}", EntityNamePrivacy.GetEntityName(target.LogicalName), target.Id));
            ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Relationship: SchemaName={0}, PrimaryEntityRole={1}", relationship.SchemaName, relationship.PrimaryEntityRole));

            foreach (var entity in relatedEntities)
            {
                ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Related: LogicalName={0}, Id={1}", EntityNamePrivacy.GetEntityName(entity.LogicalName), entity.Id));
            }

            var entities = new List <EntityReference>();

            if (this.EventHubJobSettings.IsEnabled)
            {
                //logic to ignore to get Intersect entity which we already have in eventhub model.
                EntityReference intersectEntity = new EntityReference();
                intersectEntity.LogicalName = target.LogicalName;
                intersectEntity.Id          = target.Id;
                entities.Add(intersectEntity);
            }
            else
            {
                // validate that the relationships do in fact not exist by querying for the intersects
                entities = map.Using(ContentMapLockType.Read, () => RetrieveDisassociatedIntersectEntities(context, map, target, relationship, relatedEntities).ToList());
            }

            if (entities != null)
            {
                // add intersect entities to the content map

                map.Using(ContentMapLockType.Write, () => map.RemoveRange(entities));
            }
        }
        private ContentMap GetContentMap(CrmDbContext context)
        {
            ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("LockTimeout={0}", this.LockTimeout));

            var sw = Stopwatch.StartNew();

            var solution   = this.SolutionDefinitionProvider.GetSolution();
            var parameters = this.SolutionDefinitionProvider.GetQueryParameters();
            var map        = new ContentMap(solution)
            {
                LockTimeout = this.LockTimeout.GetValueOrDefault(TimeSpan.FromMinutes(1))
            };
            var entities = this.GetEntities(context, map.Solution, parameters).ToList();

            map.Using(ContentMapLockType.Write, () => this.BuildContentMap(map, entities));

            sw.Stop();

            ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Duration: {0} ms", sw.ElapsedMilliseconds));

            return(map);
        }
        private static void Refresh(CrmDbContext context, ContentMap map, List <EntityReference> references)
        {
            if (references.Count > 0)
            {
                references[0].ThrowOnNull("reference");
                EntityDefinition          ed;
                Dictionary <Guid, Entity> mapEntities = new Dictionary <Guid, Entity>();
                bool getEntityDefinition = map.Solution.Entities.TryGetValue(references[0].LogicalName, out ed);

                if (getEntityDefinition)
                {
                    List <Guid> guids = new List <Guid>();
                    foreach (var reference in references)
                    {
                        reference.ThrowOnNull("reference");
                        guids.Add(reference.Id);
                        ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("LogicalName={0}, Id={1}", EntityNamePrivacy.GetEntityName(reference.LogicalName), reference.Id));
                    }
                    try
                    {
                        string primaryEntityAttribute = EventHubBasedInvalidation.CrmChangeTrackingManager.Instance.TryGetPrimaryKey(references[0].LogicalName);

                        var entities = RetrieveCRMRecords(context, primaryEntityAttribute, references[0], ed, guids);
                        foreach (var entity in entities)
                        {
                            mapEntities.Add(entity.Id, entity);
                        }

                        ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Retrieve Multiple Response for Entity {0} has Record Count {1} , Refrence Count {2} ", references[0].LogicalName, entities.Count, references.Count));

                        // check if the entity is inactive according to the definition
                        foreach (var reference in references)
                        {
                            var entity = mapEntities.ContainsKey(reference.Id) ? (Entity)mapEntities[reference.Id] : null;

                            // Check if the entity matches on the defined relationships.
                            if (!ed.ShouldIncludeInContentMap(entity))
                            {
                                continue;
                            }

                            var option = entity != null?entity.GetAttributeValue <OptionSetValue>("statecode") : null;

                            var isActive = ed.ActiveStateCode == null || (option != null && ed.ActiveStateCode.Value == option.Value);
                            var node     = map.Using(ContentMapLockType.Write, () => entity != null
                                                                ? isActive
                                                                        ? map.Replace(entity)
                                                                        : map.Deactivate(reference)
                                                                : map.Remove(reference));
                        }
                    }
                    catch (FaultException <OrganizationServiceFault> )
                    {
                        // an exception occurs when trying to retrieve a non-existing entity
                        ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("An exception occurs when trying to retrieve a non-existing entity"));
                    }
                }
                else
                {
                    ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Unknown: logicalName={0}", EntityNamePrivacy.GetEntityName(references[0].LogicalName)));
                }
            }
        }
        private static EntityNode Refresh(CrmDbContext context, ContentMap map, EntityReference reference)
        {
            reference.ThrowOnNull("reference");

            ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("LogicalName={0}, Id={1}", EntityNamePrivacy.GetEntityName(reference.LogicalName), reference.Id));

            EntityDefinition ed;

            if (map.Solution.Entities.TryGetValue(reference.LogicalName, out ed))
            {
                // retrieve a fresh entity which also acts as a backend validation

                var fetch = ed.CreateFetch();

                Entity entity = null;

                try
                {
                    string primaryIdAttribute = EventHubBasedInvalidation.CrmChangeTrackingManager.Instance.TryGetPrimaryKey(reference.LogicalName);

                    // The condition for the filter on primary key
                    var primaryAttributeCondition = new Condition
                    {
                        Attribute = primaryIdAttribute,
                        Operator  = ConditionOperator.Equal,
                        Value     = reference.Id
                    };

                    var attributes = fetch.Entity.Attributes;
                    var fQuery     = new Fetch
                    {
                        Distinct  = true,
                        SkipCache = true,
                        Entity    = new FetchEntity
                        {
                            Name       = reference.LogicalName,
                            Attributes = attributes,
                            Filters    = new List <Filter>()
                            {
                                new Filter
                                {
                                    Type       = LogicalOperator.And,
                                    Conditions = new List <Condition>()
                                    {
                                        primaryAttributeCondition
                                    }
                                }
                            }
                        }
                    };

                    entity = context.Service.RetrieveSingle(fQuery, true, true);
                }
                catch (FaultException <OrganizationServiceFault> fe)
                {
                    // an exception occurs when trying to retrieve a non-existing entity

                    if (!fe.Message.EndsWith("Does Not Exist"))
                    {
                        throw;
                    }
                }

                // Check if the entity matches on the defined relationships.
                if (!ed.ShouldIncludeInContentMap(entity))
                {
                    return(null);
                }

                // check if the entity is inactive according to the definition
                var option = entity != null?entity.GetAttributeValue <OptionSetValue>("statecode") : null;

                var isActive = ed.ActiveStateCode == null || (option != null && ed.ActiveStateCode.Value == option.Value);

                var node = map.Using(ContentMapLockType.Write, () => entity != null
                                        ? (isActive
                                                ? map.Replace(entity)
                                                : map.Deactivate(reference))
                                        : map.Remove(reference));

                return(node);
            }

            ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Unknown: logicalName={0}", EntityNamePrivacy.GetEntityName(reference.LogicalName)));

            return(null);
        }