Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
            }
        }
Esempio n. 4
0
        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);
                }
            }
        }
Esempio n. 5
0
        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);
        }