public override void Disassociate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities) { if (DisassociateAction != null) { DisassociateAction(Service, entityName, entityId, relationship, relatedEntities); } else if (DisassociateActions != null) { if (DisassociateCache == null) { DisassociateCache = Service; foreach (var disassociate in DisassociateActions) { DisassociateCache = new FakeIOrganizationService(DisassociateCache) { DisassociateAction = disassociate }; } } DisassociateCache.Disassociate(entityName, entityId, relationship, relatedEntities); } else { if (ExecutionTracingEnabled) { Timer.Time(DisassociateInternal, new Tuple <string, Guid, Relationship, EntityReferenceCollection>(entityName, entityId, relationship, relatedEntities), "Disassociate {0}:{1} using relationship {2} to releated Entities {3}: {4}", entityName, entityId, relationship, relatedEntities.Select(e => e.GetNameId()).ToCsv()); } else { Service.Disassociate(entityName, entityId, relationship, relatedEntities); } } }
public void Associate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities) { if (!relatedEntities.Any()) { throw new ArgumentException("Must contain at least one related entity!", nameof(relatedEntities)); } if (relatedEntities.Any(e => e.LogicalName != relatedEntities.First().LogicalName)) { throw new NotImplementedException("Don't currently Support different Entity Types for related Entities!"); } if (relationship.PrimaryEntityRole.GetValueOrDefault(EntityRole.Referenced) == EntityRole.Referencing) { throw new NotImplementedException("Referencing Not Currently Implemented"); } var referencedIdName = EntityHelper.GetIdAttributeName(entityName); var referencingIdName = EntityHelper.GetIdAttributeName(relatedEntities.First().LogicalName); if (referencedIdName == referencingIdName) { referencedIdName += "one"; referencingIdName += "two"; } foreach (var relation in relatedEntities.Select(relatedEntity => new Entity(relationship.SchemaName) { [referencedIdName] = entityId, [referencingIdName] = relatedEntity.Id })) { Service.Create(relation); } }
/// <summary> /// Creates the Association /// </summary> /// <param name="service">The service.</param> /// <param name="entityName">Type: String. The logical name of the entity that is specified in the <paramref name="entityId" /> parameter.</param> /// <param name="entityId">Type: Guid. The Id of the record to which the related records are associated.</param> /// <param name="relationship">Type: <see cref="T:Microsoft.Xrm.Sdk.Relationship" />. The name of the relationship to be used to create the link.</param> /// <param name="relatedEntities">Type: <see cref="T:Microsoft.Xrm.Sdk.EntityReferenceCollection" />. A collection of entity references (references to records) to be associated.</param> public Guid[] CreateAssociation(IOrganizationService service, string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities) { if (!DefinitionsByRelationshipName.TryGetValue(relationship.SchemaName, out var definition)) { throw new KeyNotFoundException($"Schema name {relationship.SchemaName} was not found in the DefinitionsByRelationshipName dictionary."); } var primaryAttributeName = entityName == definition.PrimaryEntityType ? definition.PrimaryEntityIdName : definition.AssociatedEntityIdName; var associatedAttributeName = entityName == definition.PrimaryEntityType ? definition.AssociatedEntityIdName : definition.PrimaryEntityIdName; var ids = new List <Guid>(); foreach (var relation in relatedEntities.Select(relatedEntity => new Entity(definition.AssociationLogicalName) { [primaryAttributeName] = entityId, [associatedAttributeName] = relatedEntity.Id })) { ids.Add(service.Create(relation)); } return(ids.ToArray()); }
public override void Associate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities) { if (AssociateAction != null) { AssociateAction(Service, entityName, entityId, relationship, relatedEntities); } else if (AssociateActions != null) { if (AssociateCache == null) { AssociateCache = Service; foreach (var action in AssociateActions) { AssociateCache = new FakeIOrganizationService(AssociateCache) { AssociateAction = action }; } } AssociateCache.Associate(entityName, entityId, relationship, relatedEntities); } else { if (ExecutionTracingEnabled) { Timer.Time(AssociateInternal, new Tuple <string, Guid, Relationship, EntityReferenceCollection>(entityName, entityId, relationship, relatedEntities), "Associate {0}:{1} using relationship {2} to releated Entities {3}: {4}", entityName, entityId, relationship, String.Join(", ", relatedEntities.Select(e => e.GetNameId()))); } else { Service.Associate(entityName, entityId, relationship, relatedEntities); } } }
public void Disassociate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities) { if (!relatedEntities.Any()) { throw new ArgumentException("Must contain at least one related entity!", "relatedEntities"); } if (relatedEntities.Any(e => e.LogicalName != relatedEntities.First().LogicalName)) { throw new NotImplementedException("Don't currently Support different Entity Types for related Entities!"); } if (relationship.PrimaryEntityRole.GetValueOrDefault(EntityRole.Referenced) == EntityRole.Referencing) { throw new NotImplementedException("Referencing Not Currently Implemented"); } var referencedIdName = EntityHelper.GetIdAttributeName(entityName); var referencingIdName = EntityHelper.GetIdAttributeName(relatedEntities.First().LogicalName); if (referencedIdName == referencingIdName) { referencedIdName += "one"; referencingIdName += "two"; } foreach (var entity in relatedEntities. Select(e => QueryExpressionFactory.Create(relationship.SchemaName, referencedIdName, entityId, referencingIdName, e.Id)). Select(qe => Service.RetrieveMultiple(qe).ToEntityList <Entity>().FirstOrDefault()). Where(entity => entity != null)) { Service.Delete(entity); } }
/// <summary> /// Iterates and displays the entity references in the entity reference collection. /// </summary> /// <param name="collection">The collection.</param> /// <param name="info">Optional arguments.</param> public static string ToStringDebug(this EntityReferenceCollection collection, StringDebugInfo info = null) { if (collection == null) { return("null"); } return(Wrap("[", collection.Select(r => r.ToStringDebug()), "]", info)); }
private void Associate1ToN(Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities, string referencedIdName, string referencingIdName) { foreach (var relation in relatedEntities.Select(relatedEntity => new Entity(relationship.SchemaName) { [referencedIdName] = entityId, [referencingIdName] = relatedEntity.Id })) { Service.Create(relation); } }
private void Disassociate1ToN(Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities, string referencedIdName, string referencingIdName) { foreach (var entity in relatedEntities .Select(e => QueryExpressionFactory.Create(relationship.SchemaName, referencedIdName, entityId, referencingIdName, e.Id)) .Select(qe => Service.RetrieveMultiple(qe).ToEntityList <Entity>().FirstOrDefault()) .Where(entity => entity != null)) { Service.Delete(entity); } }
public void Disassociate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities) { bag.trace($"Disassociate({entityName}, {entityId}, {relationship.SchemaName}, {relatedEntities.Count})"); if (bag.TracingService.Verbose) { bag.trace("Disassociated record(s):{0}", relatedEntities.Select(r => $"\n {r.LogicalName} {r.Id} {r.Name}")); } var watch = Stopwatch.StartNew(); service.Disassociate(entityName, entityId, relationship, relatedEntities); watch.Stop(); bag.trace($"Disassociated in: {watch.ElapsedMilliseconds} ms"); }
protected void HandleOwnerTeamMembership(LocalPluginContext localContext, EntityReference target, EntityReferenceCollection refs) { localContext.Trace($"Handling TeamMembership '{localContext.PluginExecutionContext.MessageName}' operation via 'opc_teams_teams_owneraadassociation'."); // Isolate teamIds and queueIds Guid[] affectedAADTeamIds, ownerTeamId, unaffectedTeamIds = null; affectedAADTeamIds = refs.Select(t => t.Id).ToArray(); ownerTeamId = new[] { target.Id }; localContext.Trace($"There is {affectedAADTeamIds.Count()} affected AAD teams ({string.Join(",", affectedAADTeamIds)})"); localContext.Trace($"There is {ownerTeamId.Count()} affected owner teams: {string.Join(",", ownerTeamId)}"); // If it's a disassociate operation we will need all the AAD teams associated to the owner team to ensure // the user does not have access through another team if (localContext.PluginExecutionContext.MessageName == PluginMessage.Disassociate) { // Build and execute query to get all AAD teams associated to the owner team that should not be affected by this change unaffectedTeamIds = FetchUnaffectedAADTeamsByOwnerTeams(localContext, ownerTeamId, affectedAADTeamIds); localContext.Trace($"There is {unaffectedTeamIds.Count()} unaffected AAD teams ({string.Join(",", unaffectedTeamIds)})"); } // Build and execute fetch query to get all users associated to AAD teams but only keep the ones which are not associated to unaffected AAD teams var usersInTeams = FetchUsersByTeams(localContext, unaffectedTeamIds, affectedAADTeamIds, ownerTeamId); localContext.Trace($"There is {usersInTeams.Count()} users affected ({string.Join(",", usersInTeams)})"); // Add owner teams to users who don't have the owner team already. if (localContext.PluginExecutionContext.MessageName == PluginMessage.Associate) { // Build and execute query to get all users associated to the owner teams var usersInOwnerTeams = FetchOwnerTeamMembershipByOwnerTeams(localContext, ownerTeamId); localContext.Trace($"There is {usersInOwnerTeams.Count()} users associated to affected owner teams: ({string.Join(",", usersInOwnerTeams)})"); // Add owner teams to users who don't have the owner team already. var toAdd = usersInTeams.Except(usersInOwnerTeams).Select(u => new EntityReference("systemuser", u)).ToList(); foreach (var teamId in ownerTeamId) { localContext.Trace($"Adding {toAdd.Count()} users to owner team '{teamId}'"); localContext.OrganizationService.Associate("team", teamId, new Relationship("teammembership_association"), new EntityReferenceCollection(toAdd)); } } else if (localContext.PluginExecutionContext.MessageName == PluginMessage.Disassociate) { var toRemove = usersInTeams.Select(u => new EntityReference("systemuser", u)).ToList(); foreach (var teamId in ownerTeamId) { localContext.Trace($"Removing {toRemove.Count()} users from owner team '{teamId}'"); localContext.OrganizationService.Disassociate("team", teamId, new Relationship("teammembership_association"), new EntityReferenceCollection(toRemove)); } } }
private void AddMembersToTeam(Guid?TeamId, EntityReferenceCollection Users, IOrganizationService service) { Guid[] UserIds; //get user AddMembersTeamRequest addRequest = new AddMembersTeamRequest(); if (TeamId.HasValue) { addRequest.TeamId = TeamId.Value; UserIds = Users.Select(x => x.Id).ToArray(); addRequest.MemberIds = UserIds; tracingService.Trace("before updating "); service.Execute(addRequest); tracingService.Trace("after updating "); } }
public override void Execute() { var record = _crmContext.RecordCache.Get(_alias); var md = GlobalTestingContext.Metadata.GetEntityMetadata(record.LogicalName, EntityFilters.Relationships); var relationship = md.ManyToManyRelationships.FirstOrDefault(r => (r.Entity1LogicalName == record.LogicalName && r.Entity2LogicalName == _relatedEntityName) || (r.Entity1LogicalName == _relatedEntityName && r.Entity2LogicalName == record.LogicalName)); if (relationship == null) { throw new TestExecutionException(Constants.ErrorCodes.N_N_RELATIONSHIP_NOT_FOUND, record.LogicalName, _relatedEntityName); } Logger.WriteLine($"Using relationship {relationship.SchemaName}"); EntityReferenceCollection records = new EntityReferenceCollection(); foreach (var row in _expectedRecords.Rows) { var lookupValue = ObjectConverter.GetLookupValue(_crmContext, row[Constants.SpecFlow.TABLE_VALUE], _relatedEntityName); if (lookupValue == null) { throw new TestExecutionException(Constants.ErrorCodes.RECORD_NOT_FOUND, row[Constants.SpecFlow.TABLE_VALUE], _relatedEntityName); } records.Add(lookupValue); } var currentRecordFieldName = relationship.Entity1LogicalName == record.LogicalName ? relationship.Entity1IntersectAttribute : relationship.Entity2IntersectAttribute; var relatedFieldName = relationship.Entity1LogicalName == _relatedEntityName ? relationship.Entity1IntersectAttribute : relationship.Entity2IntersectAttribute; var query = new QueryExpression(relationship.IntersectEntityName); query.ColumnSet.AddColumn(relatedFieldName); query.Criteria.AddCondition(currentRecordFieldName, ConditionOperator.Equal, record.Id); query.Criteria.AddCondition(relatedFieldName, ConditionOperator.In, records.Select(r => (object)r.Id).ToArray()); var result = GlobalTestingContext.ConnectionManager.CurrentConnection.RetrieveMultiple(query); Assert.AreEqual(records.Count, result.Entities.Count, $"Different records: {string.Join(", ", records.Where(r => !result.Entities.Select(e => e.GetAttributeValue<Guid>(relatedFieldName)).Contains(r.Id)).Select(r => r.Name))}"); }
public void ApplyRulesToUser(EntityReferenceCollection ec, Guid userId, bool isOutlookFilter) { var tempUserId = ((CrmServiceClient)service).CallerId; ((CrmServiceClient)service).CallerId = userId; try { // TODO ICI var existingQueries = service.RetrieveMultiple(new QueryExpression("userquery") { Criteria = new FilterExpression { Conditions = { new ConditionExpression("parentqueryid", ConditionOperator.In, ec.Select(e => e.Id).ToArray()) } } }).Entities; var transac = new ExecuteTransactionRequest { Requests = new OrganizationRequestCollection(), ReturnResponses = false }; foreach (var query in existingQueries) { transac.Requests.Add(new DeleteRequest { Target = query.ToEntityReference() }); } transac.Requests.Add(new InstantiateFiltersRequest { UserId = userId, TemplateCollection = ec }); service.Execute(transac); } finally { ((CrmServiceClient)service).CallerId = tempUserId; } }
/// <inheritdoc /> public void Disassociate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities) { var message = Settings.LogDetailedRequests ? $"Disassociate Request for {entityName}, with Id {entityId}, Relationship {relationship.SchemaName}, and Related Entities {relatedEntities.Select(e => e.ToStringDebug()).ToCsv()}." : "Disassociate Request"; if (Settings.TimeRequests) { var timer = new Stopwatch(); try { TraceStart(message); timer.Start(); Service.Disassociate(entityName, entityId, relationship, relatedEntities); return; } finally { TraceEnd(timer); } } TraceExecute(message); Service.Disassociate(entityName, entityId, relationship, relatedEntities); }
public override void Disassociate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities) { if (DisassociateAction != null) { DisassociateAction(Service, entityName, entityId, relationship, relatedEntities); } else if (DisassociateActions != null) { if (DisassociateCache == null) { DisassociateCache = Service; foreach (var disassociate in DisassociateActions) { DisassociateCache = new FakeIOrganizationService(DisassociateCache) {DisassociateAction = disassociate}; } } DisassociateCache.Disassociate(entityName, entityId, relationship, relatedEntities); } else { if (ExecutionTracingEnabled) { Timer.Time(DisassociateInternal, new Tuple<string, Guid, Relationship, EntityReferenceCollection>(entityName, entityId, relationship, relatedEntities), "Disassociate {0}:{1} using relationship {2} to releated Entities {3}: {4}", entityName, entityId, relationship, String.Join(", ", relatedEntities.Select(e => e.GetNameId()))); } else { Service.Disassociate(entityName, entityId, relationship, relatedEntities); } } }
protected void HandleAADTeamMembership(LocalPluginContext localContext, EntityReference target, EntityReferenceCollection refs) { localContext.Trace($"Handling TeamMembership '{localContext.PluginExecutionContext.MessageName}' operation via 'teammembership_association'."); // Regardless of which side the relation was triggered; isolate teamIds and userIds Guid[] systemuserIds, affectedTeamIds, unaffectedTeamIds = null; systemuserIds = target.LogicalName == "systemuser" ? new[] { target.Id } : refs.Select(u => u.Id).ToArray(); affectedTeamIds = target.LogicalName == "team" ? new[] { target.Id } : refs.Select(t => t.Id).ToArray(); localContext.Trace($"There is {affectedTeamIds.Count()} affected teams ({string.Join(",", affectedTeamIds)})"); localContext.Trace($"There is {systemuserIds.Count()} affected users ({string.Join(",", systemuserIds)})"); if (!systemuserIds.Any() || !affectedTeamIds.Any()) { return; } // If it's a disassociate operation we will need all the AAD teams associated to the user to ensure // the user does not have access through another team if (localContext.PluginExecutionContext.MessageName == PluginMessage.Disassociate) { // Build and execute fetch query to get all AAD teams of the users which should not be affected by this change unaffectedTeamIds = FetchUnaffectedTeamsByUsers(localContext, systemuserIds, affectedTeamIds); localContext.Trace($"There is {unaffectedTeamIds.Count()} unaffected teams: {string.Join(",", unaffectedTeamIds)}"); } // Build and execute fetch query to fetch all owner teams associated to AAD teams but only keep the ones which are not referenced in unaffected teams var ownerTeams = FetchAffectedOwnerTeams(localContext, unaffectedTeamIds, affectedTeamIds); localContext.Trace($"There are {ownerTeams.Count()} owner teams affected: ({string.Join(",", ownerTeams)})"); // Build and execute fetch query to fetch all teams with their team types. var teams = FetchAllTeamsWithType(localContext); if (localContext.PluginExecutionContext.MessageName == PluginMessage.Associate) { // Build and execute query to fetch owner teams associated to users var userOwnerTeams = FetchOwnerTeamMembershipByUsers(localContext, systemuserIds); userOwnerTeams = userOwnerTeams.Except(teams.Where(t => t.TeamType == TeamTeamType.AADSecurityGroup).Select(t => t.Id).ToArray()).ToArray(); localContext.Trace($"There are {userOwnerTeams.Count()} user associated to affected owner teams: ({string.Join(",", userOwnerTeams)})"); // Only get the delta of owner teams to be added based on the owner teams the user is already affected to. var toAdd = ownerTeams.Except(userOwnerTeams) .Select(t => new EntityReference("team", t)) .ToList(); foreach (var userid in systemuserIds) { localContext.Trace($"Adding {toAdd.Count()} owner teams to user '{userid}'"); localContext.OrganizationService.Associate("systemuser", userid, new Relationship("teammembership_association"), new EntityReferenceCollection(toAdd)); } } else if (localContext.PluginExecutionContext.MessageName == PluginMessage.Disassociate) { var toRemove = ownerTeams.Select(t => new EntityReference("team", t)).ToList(); foreach (var userid in systemuserIds) { localContext.Trace($"Removing {toRemove.Count()} owner teams from user '{userid}'"); localContext.OrganizationService.Disassociate("systemuser", userid, new Relationship("teammembership_association"), new EntityReferenceCollection(toRemove)); } } }
public static List <PluginMessageEntityReference> ToPluginMessageEntityReferenceCollection(this EntityReferenceCollection entities) { return(new List <PluginMessageEntityReference>(entities.Select(reference => reference.ToPluginMessageEntityReference()))); }