private Tuple <object, string, Guid> GetEntityInfo(OrganizationRequest request) { Mappings.EntityImageProperty.TryGetValue(request.GetType(), out string key); object obj = null; if (key != null) { obj = request.Parameters[key]; } if (request is WinOpportunityRequest || request is LoseOpportunityRequest) { var close = request is WinOpportunityRequest ? (request as WinOpportunityRequest).OpportunityClose : (request as LoseOpportunityRequest).OpportunityClose; obj = close.GetAttributeValue <EntityReference>("opportunityid"); } else if (request is RetrieveMultipleRequest) { var retrieve = request as RetrieveMultipleRequest; string entityName = null; switch (retrieve.Query) { case FetchExpression fe: var qe = XmlHandling.FetchXmlToQueryExpression(fe.Query); entityName = qe.EntityName; break; case QueryExpression query: entityName = query.EntityName; break; case QueryByAttribute qba: entityName = qba.EntityName; break; } if (entityName != null) { return(new Tuple <object, string, Guid>(new EntityReference { LogicalName = entityName, Id = Guid.Empty }, entityName, Guid.Empty)); } } if (obj is Entity entity) { return(new Tuple <object, string, Guid>(obj, entity.LogicalName, entity.Id)); } if (obj is EntityReference entityRef) { return(new Tuple <object, string, Guid>(obj, entityRef.LogicalName, entityRef.Id)); } return(null); }
private FetchXmlToQueryExpressionResponse HandleFetchXmlToQueryExpression(OrganizationRequest orgRequest, EntityReference userRef) { var request = MakeRequest <FetchXmlToQueryExpressionRequest>(orgRequest); var resp = new FetchXmlToQueryExpressionResponse(); resp.Results["Query"] = XmlHandling.FetchXmlToQueryExpression(request.FetchXml); return(resp); }
public static EntityReference GetPrimaryEntityReferenceFromQuery(QueryBase query) { switch (query) { case FetchExpression fe: return(new EntityReference(XmlHandling.FetchXmlToQueryExpression(fe.Query).EntityName, Guid.Empty)); case QueryExpression qe: return(new EntityReference(qe.EntityName, Guid.Empty)); case QueryByAttribute qba: return(new EntityReference(qba.EntityName, Guid.Empty)); default: return(null); } }
internal void AddRelatedEntities(Entity entity, RelationshipQueryCollection relatedEntityQuery, EntityReference userRef) { foreach (var relQuery in relatedEntityQuery) { var relationship = relQuery.Key; var queryExpr = relQuery.Value as QueryExpression; if (queryExpr == null) { queryExpr = XmlHandling.FetchXmlToQueryExpression(((FetchExpression)relQuery.Value).Query); } var relationshipMetadata = Utility.GetRelatedEntityMetadata(metadata.EntityMetadata, queryExpr.EntityName, relationship.SchemaName); var oneToMany = relationshipMetadata as OneToManyRelationshipMetadata; var manyToMany = relationshipMetadata as ManyToManyRelationshipMetadata; if (oneToMany != null) { if (relationship.PrimaryEntityRole == EntityRole.Referencing) { var entityAttributes = db.GetEntityOrNull(entity.ToEntityReference()).Attributes; if (entityAttributes.ContainsKey(oneToMany.ReferencingAttribute) && entityAttributes[oneToMany.ReferencingAttribute] != null) { var referencingGuid = Utility.GetGuidFromReference(entityAttributes[oneToMany.ReferencingAttribute]); queryExpr.Criteria.AddCondition( new ConditionExpression(oneToMany.ReferencedAttribute, ConditionOperator.Equal, referencingGuid)); } } else { queryExpr.Criteria.AddCondition( new ConditionExpression(oneToMany.ReferencingAttribute, ConditionOperator.Equal, entity.Id)); } } if (manyToMany != null) { if (db[manyToMany.IntersectEntityName].Count() > 0) { var conditions = new FilterExpression(LogicalOperator.Or); if (entity.LogicalName == manyToMany.Entity1LogicalName) { queryExpr.EntityName = manyToMany.Entity2LogicalName; var relatedIds = db[manyToMany.IntersectEntityName] .Where(row => row.GetColumn <Guid>(manyToMany.Entity1IntersectAttribute) == entity.Id) .Select(row => row.GetColumn <Guid>(manyToMany.Entity2IntersectAttribute)); foreach (var id in relatedIds) { conditions.AddCondition( new ConditionExpression(null, ConditionOperator.Equal, id)); } } else { queryExpr.EntityName = manyToMany.Entity1LogicalName; var relatedIds = db[manyToMany.IntersectEntityName] .Where(row => row.GetColumn <Guid>(manyToMany.Entity2IntersectAttribute) == entity.Id) .Select(row => row.GetColumn <Guid>(manyToMany.Entity1IntersectAttribute)); foreach (var id in relatedIds) { conditions.AddCondition( new ConditionExpression(null, ConditionOperator.Equal, id)); } } queryExpr.Criteria = conditions; } } var entities = new EntityCollection(); if ((oneToMany != null || manyToMany != null) && queryExpr.Criteria.Conditions.Count > 0) { var handler = RequestHandlers.Find(x => x is RetrieveMultipleRequestHandler); var req = new RetrieveMultipleRequest { Query = queryExpr }; var resp = handler.Execute(req, userRef) as RetrieveMultipleResponse; entities = resp.EntityCollection; } if (entities.Entities.Count() > 0) { entity.RelatedEntities.Add(relationship, entities); } } }
internal override OrganizationResponse Execute(OrganizationRequest orgRequest, EntityReference userRef) { var request = MakeRequest <RetrieveMultipleRequest>(orgRequest); var queryExpr = request.Query as QueryExpression; var fetchExpr = request.Query as FetchExpression; if (queryExpr == null) { queryExpr = XmlHandling.FetchXmlToQueryExpression(fetchExpr.Query); } var collection = new EntityCollection(); db.PrefillDBWithOnlineData(queryExpr); var rows = db.GetDBEntityRows(queryExpr.EntityName); if (db[queryExpr.EntityName].Count() > 0) { foreach (var row in rows) { if (!Utility.MatchesCriteria(row, queryExpr.Criteria)) { continue; } var entity = row.ToEntity(); var toAdd = core.GetStronglyTypedEntity(entity, row.Metadata, null); if (queryExpr.LinkEntities.Count > 0) { foreach (var linkEntity in queryExpr.LinkEntities) { collection.Entities.AddRange( GetAliasedValuesFromLinkentity(linkEntity, entity, toAdd, db)); } } else { collection.Entities.Add(toAdd); } } } var filteredEntities = new EntityCollection(); filteredEntities.Entities.AddRange(collection.Entities.Where(e => security.HasPermission(e, AccessRights.ReadAccess, userRef))); var orders = queryExpr.Orders; var orderedCollection = new EntityCollection(); // TODO: Check the order that the orders are executed in is correct if (orders.Count > 2) { throw new MockupException("Number of orders are greater than 2, unsupported in crm"); } else if (orders.Count == 1) { if (orders.First().OrderType == OrderType.Ascending) { orderedCollection.Entities.AddRange(filteredEntities.Entities.OrderBy(x => Utility.GetComparableAttribute(x.Attributes[orders[0].AttributeName]))); } else { orderedCollection.Entities.AddRange(filteredEntities.Entities.OrderByDescending(x => Utility.GetComparableAttribute(x.Attributes[orders[0].AttributeName]))); } } else if (orders.Count == 2) { if (orders[0].OrderType == OrderType.Ascending && orders[1].OrderType == OrderType.Ascending) { orderedCollection.Entities.AddRange(filteredEntities.Entities .OrderBy(x => Utility.GetComparableAttribute(x.Attributes[orders[0].AttributeName])) .ThenBy(x => Utility.GetComparableAttribute(x.Attributes[orders[1].AttributeName]))); } else if (orders[0].OrderType == OrderType.Ascending && orders[1].OrderType == OrderType.Descending) { orderedCollection.Entities.AddRange(filteredEntities.Entities .OrderBy(x => Utility.GetComparableAttribute(x.Attributes[orders[0].AttributeName])) .ThenByDescending(x => Utility.GetComparableAttribute(x.Attributes[orders[1].AttributeName]))); } else if (orders[0].OrderType == OrderType.Descending && orders[1].OrderType == OrderType.Ascending) { orderedCollection.Entities.AddRange(filteredEntities.Entities .OrderByDescending(x => Utility.GetComparableAttribute(x.Attributes[orders[0].AttributeName])) .ThenBy(x => Utility.GetComparableAttribute(x.Attributes[orders[1].AttributeName]))); } else if (orders[0].OrderType == OrderType.Descending && orders[1].OrderType == OrderType.Descending) { orderedCollection.Entities.AddRange(filteredEntities.Entities .OrderByDescending(x => Utility.GetComparableAttribute(x.Attributes[orders[0].AttributeName])) .ThenByDescending(x => Utility.GetComparableAttribute(x.Attributes[orders[1].AttributeName]))); } } var colToReturn = new EntityCollection(); if (orderedCollection.Entities.Count != 0) { foreach (var entity in orderedCollection.Entities) { KeepAttributesAndAliasAttributes(entity, queryExpr.ColumnSet); } colToReturn = orderedCollection; } else { foreach (var entity in filteredEntities.Entities) { KeepAttributesAndAliasAttributes(entity, queryExpr.ColumnSet); } colToReturn = filteredEntities; } var resp = new RetrieveMultipleResponse(); resp.Results["EntityCollection"] = colToReturn; return(resp); }
internal override OrganizationResponse Execute(OrganizationRequest orgRequest, EntityReference userRef) { var request = MakeRequest <RetrieveMultipleRequest>(orgRequest); var queryExpr = request.Query as QueryExpression; var fetchExpr = request.Query as FetchExpression; var queryByAttr = request.Query as QueryByAttribute; if (fetchExpr != null) { queryExpr = XmlHandling.FetchXmlToQueryExpression(fetchExpr.Query); } else if (queryByAttr != null) { queryExpr = Utility.QueryByAttributeToQueryExpression(queryByAttr); } if (queryExpr.EntityName == null) { throw new FaultException("The 'RetrieveMultiple' method does not support entities of type 'none'"); } FillAliasIfEmpty(queryExpr); var collection = new EntityCollection(); db.PrefillDBWithOnlineData(queryExpr); var rows = db.GetDBEntityRows(queryExpr.EntityName); if (db[queryExpr.EntityName].Count() > 0) { #if !(XRM_MOCKUP_2011 || XRM_MOCKUP_2013) foreach (var row in rows.ToList()) { core.ExecuteCalculatedFields(row); } #endif foreach (var row in rows) { var entity = row.ToEntity(); var toAdd = core.GetStronglyTypedEntity(entity, row.Metadata, null); Utility.SetFormmattedValues(db, toAdd, row.Metadata); if (queryExpr.LinkEntities.Count > 0) { foreach (var linkEntity in queryExpr.LinkEntities) { var alliasedValues = GetAliasedValuesFromLinkentity(linkEntity, entity, toAdd, db); collection.Entities.AddRange( alliasedValues .Where(e => Utility.MatchesCriteria(e, queryExpr.Criteria))); } } else if (Utility.MatchesCriteria(toAdd, queryExpr.Criteria)) { collection.Entities.Add(toAdd); } } } var filteredEntities = new EntityCollection(); filteredEntities.Entities.AddRange(collection.Entities.Where(e => security.HasPermission(e, AccessRights.ReadAccess, userRef))); var orders = queryExpr.Orders; var orderedCollection = new EntityCollection(); // TODO: Check the order that the orders are executed in is correct if (orders.Count > 2) { throw new MockupException("Number of orders are greater than 2, unsupported in crm"); } else if (orders.Count == 1) { if (orders.First().OrderType == OrderType.Ascending) { orderedCollection.Entities.AddRange(filteredEntities.Entities.OrderBy(x => Utility.GetComparableAttribute(x.Attributes[orders[0].AttributeName]))); } else { orderedCollection.Entities.AddRange(filteredEntities.Entities.OrderByDescending(x => Utility.GetComparableAttribute(x.Attributes[orders[0].AttributeName]))); } } else if (orders.Count == 2) { if (orders[0].OrderType == OrderType.Ascending && orders[1].OrderType == OrderType.Ascending) { orderedCollection.Entities.AddRange(filteredEntities.Entities .OrderBy(x => Utility.GetComparableAttribute(x.Attributes[orders[0].AttributeName])) .ThenBy(x => Utility.GetComparableAttribute(x.Attributes[orders[1].AttributeName]))); } else if (orders[0].OrderType == OrderType.Ascending && orders[1].OrderType == OrderType.Descending) { orderedCollection.Entities.AddRange(filteredEntities.Entities .OrderBy(x => Utility.GetComparableAttribute(x.Attributes[orders[0].AttributeName])) .ThenByDescending(x => Utility.GetComparableAttribute(x.Attributes[orders[1].AttributeName]))); } else if (orders[0].OrderType == OrderType.Descending && orders[1].OrderType == OrderType.Ascending) { orderedCollection.Entities.AddRange(filteredEntities.Entities .OrderByDescending(x => Utility.GetComparableAttribute(x.Attributes[orders[0].AttributeName])) .ThenBy(x => Utility.GetComparableAttribute(x.Attributes[orders[1].AttributeName]))); } else if (orders[0].OrderType == OrderType.Descending && orders[1].OrderType == OrderType.Descending) { orderedCollection.Entities.AddRange(filteredEntities.Entities .OrderByDescending(x => Utility.GetComparableAttribute(x.Attributes[orders[0].AttributeName])) .ThenByDescending(x => Utility.GetComparableAttribute(x.Attributes[orders[1].AttributeName]))); } } var colToReturn = new EntityCollection(); if (orderedCollection.Entities.Count != 0) { foreach (var entity in orderedCollection.Entities) { KeepAttributesAndAliasAttributes(entity, queryExpr.ColumnSet); } colToReturn = orderedCollection; } else { foreach (var entity in filteredEntities.Entities) { KeepAttributesAndAliasAttributes(entity, queryExpr.ColumnSet); } colToReturn = filteredEntities; } // According to docs, should return -1 if ReturnTotalRecordCount set to false colToReturn.TotalRecordCount = queryExpr.PageInfo.ReturnTotalRecordCount ? colToReturn.Entities.Count : -1; var resp = new RetrieveMultipleResponse(); resp.Results["EntityCollection"] = colToReturn; return(resp); }
internal override OrganizationResponse Execute(OrganizationRequest orgRequest, EntityReference userRef) { var request = MakeRequest <RetrieveMultipleRequest>(orgRequest); var queryExpr = request.Query as QueryExpression; var fetchExpr = request.Query as FetchExpression; var queryByAttr = request.Query as QueryByAttribute; if (fetchExpr != null) { queryExpr = XmlHandling.FetchXmlToQueryExpression(fetchExpr.Query); } else if (queryByAttr != null) { queryExpr = Utility.QueryByAttributeToQueryExpression(queryByAttr); } if (queryExpr.EntityName == null) { throw new FaultException("The 'RetrieveMultiple' method does not support entities of type 'none'"); } FillAliasIfEmpty(queryExpr); db.PrefillDBWithOnlineData(queryExpr); var rows = db.GetDBEntityRows(queryExpr.EntityName); Console.WriteLine($"\t row count : {rows.Count().ToString()}"); var entityMetadata = metadata.EntityMetadata[queryExpr.EntityName]; #if !(XRM_MOCKUP_2011 || XRM_MOCKUP_2013) var rowBag = new ConcurrentBag <DbRow>(); //don't add the rows by passing in via the constructor as it can change the order foreach (var row in rows) { rowBag.Add(row); } foreach (var row in rowBag) { core.ExecuteCalculatedFields(row); } //get the rows again to include the calulated values rows = db.GetDBEntityRows(queryExpr.EntityName); #endif var collection = new ConcurrentBag <KeyValuePair <DbRow, Entity> >(); Parallel.ForEach(rows, row => { var entity = row.ToEntity(); var toAdd = core.GetStronglyTypedEntity(entity, row.Metadata, null); if (queryExpr.LinkEntities.Count > 0) { //foreach (var linkEntity in queryExpr.LinkEntities) Parallel.ForEach(queryExpr.LinkEntities, linkEntity => { var alliasedValues = GetAliasedValuesFromLinkentity(linkEntity, entity, toAdd, db); var matchingValues = alliasedValues.Where(e => Utility.MatchesCriteria(e, queryExpr.Criteria)); Parallel.ForEach(matchingValues, m => { if (security.HasPermission(m, AccessRights.ReadAccess, userRef)) { Utility.SetFormmattedValues(db, m, entityMetadata); collection.Add(new KeyValuePair <DbRow, Entity>(row, m)); } }); }); } else if (Utility.MatchesCriteria(toAdd, queryExpr.Criteria)) { if (security.HasPermission(toAdd, AccessRights.ReadAccess, userRef)) { Utility.SetFormmattedValues(db, toAdd, entityMetadata); collection.Add(new KeyValuePair <DbRow, Entity>(row, toAdd)); } } }); var orders = queryExpr.Orders; var orderedCollection = new EntityCollection(); // TODO: Check the order that the orders are executed in is correct if (orders == null || orders.Count == 0) { orderedCollection.Entities.AddRange(collection.OrderBy(x => x.Key.Sequence).Select(y => y.Value)); } if (orders.Count > 2) { throw new MockupException("Number of orders are greater than 2, unsupported in crm"); } else if (orders.Count == 1) { if (orders.First().OrderType == OrderType.Ascending) { orderedCollection.Entities.AddRange(collection.OrderBy(x => Utility.GetComparableAttribute(x.Value.Attributes[orders[0].AttributeName])) .ThenBy(x => x.Key.Sequence) .Select(y => y.Value)); } else { orderedCollection.Entities.AddRange(collection.OrderByDescending(x => Utility.GetComparableAttribute(x.Value.Attributes[orders[0].AttributeName])).Select(y => y.Value)); } } else if (orders.Count == 2) { if (orders[0].OrderType == OrderType.Ascending && orders[1].OrderType == OrderType.Ascending) { orderedCollection.Entities.AddRange(collection .OrderBy(x => Utility.GetComparableAttribute(x.Value.Attributes[orders[0].AttributeName])) .ThenBy(x => Utility.GetComparableAttribute(x.Value.Attributes[orders[1].AttributeName])) .ThenBy(x => x.Key.Sequence) .Select(y => y.Value)); } else if (orders[0].OrderType == OrderType.Ascending && orders[1].OrderType == OrderType.Descending) { orderedCollection.Entities.AddRange(collection .OrderBy(x => Utility.GetComparableAttribute(x.Value.Attributes[orders[0].AttributeName])) .ThenByDescending(x => Utility.GetComparableAttribute(x.Value.Attributes[orders[1].AttributeName])) .ThenBy(x => x.Key.Sequence) .Select(y => y.Value)); } else if (orders[0].OrderType == OrderType.Descending && orders[1].OrderType == OrderType.Ascending) { orderedCollection.Entities.AddRange(collection .OrderByDescending(x => Utility.GetComparableAttribute(x.Value.Attributes[orders[0].AttributeName])) .ThenBy(x => Utility.GetComparableAttribute(x.Value.Attributes[orders[1].AttributeName])) .ThenBy(x => x.Key.Sequence) .Select(y => y.Value)); } else if (orders[0].OrderType == OrderType.Descending && orders[1].OrderType == OrderType.Descending) { orderedCollection.Entities.AddRange(collection .OrderByDescending(x => Utility.GetComparableAttribute(x.Value.Attributes[orders[0].AttributeName])) .ThenByDescending(x => Utility.GetComparableAttribute(x.Value.Attributes[orders[1].AttributeName])) .ThenBy(x => x.Key.Sequence) .Select(y => y.Value)); } } var colToReturn = new EntityCollection(); if (orderedCollection.Entities.Count != 0) { Parallel.ForEach(orderedCollection.Entities, entity => { KeepAttributesAndAliasAttributes(entity, queryExpr.ColumnSet); } ); colToReturn = orderedCollection; } else { Parallel.ForEach(collection, kvp => { KeepAttributesAndAliasAttributes(kvp.Value, queryExpr.ColumnSet); } ); colToReturn = new EntityCollection(collection.Select(x => x.Value).ToList()); } // According to docs, should return -1 if ReturnTotalRecordCount set to false colToReturn.TotalRecordCount = queryExpr.PageInfo.ReturnTotalRecordCount ? colToReturn.Entities.Count : -1; var resp = new RetrieveMultipleResponse(); resp.Results["EntityCollection"] = colToReturn; return(resp); }