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); }