示例#1
0
        /// <summary>
        /// Builds relationship metadata
        /// </summary>
        /// <param name="serviceContext">Service Context</param>
        /// <param name="linkDetails">Link Details</param>
        /// <returns>Relationshi pMetadata</returns>
        private ProductAccessProvider.RelationshipMetadata BuildRelationshipMetadata(OrganizationServiceContext serviceContext, LinkDetails linkDetails)
        {
            // This is used for Mocking
            if (this.relationshipMetadataDictionary != null &&
                this.relationshipMetadataDictionary.ContainsKey(linkDetails.Entity2Name))
            {
                return(this.relationshipMetadataDictionary[linkDetails.Entity2Name]);
            }

            // Standard flow
            var entity1Metadata = GetEntityMetadata(serviceContext, linkDetails.Entity1Name);
            var entity2Metadata = linkDetails.Entity2Name == linkDetails.Entity1Name ? entity1Metadata : GetEntityMetadata(serviceContext, linkDetails.Entity2Name);

            var relationshipMetadata = new ProductAccessProvider.RelationshipMetadata();

            relationshipMetadata.Entity1PrimaryIdAttribute = entity1Metadata.PrimaryIdAttribute;
            relationshipMetadata.Entity2PrimaryIdAttribute = entity2Metadata.PrimaryIdAttribute;
            relationshipMetadata.Entity1LogicalName        = entity1Metadata.LogicalName;
            relationshipMetadata.Entity2LogicalName        = entity2Metadata.LogicalName;

            var relationshipManyToMany = entity1Metadata.ManyToManyRelationships.FirstOrDefault(r => r.SchemaName == linkDetails.RelationshipName);

            if (relationshipManyToMany != null)
            {
                relationshipMetadata.RelationshipType          = ProductAccessProvider.RelationshipType.ManyToManyRelationship;
                relationshipMetadata.Entity1LogicalName        = relationshipManyToMany.Entity2LogicalName;
                relationshipMetadata.Entity2LogicalName        = relationshipManyToMany.Entity1LogicalName;
                relationshipMetadata.Entity1IntersectAttribute = relationshipManyToMany.Entity2IntersectAttribute;
                relationshipMetadata.Entity2IntersectAttribute = relationshipManyToMany.Entity1IntersectAttribute;
                relationshipMetadata.IntersectEntityName       = relationshipManyToMany.IntersectEntityName;
                return(relationshipMetadata);
            }

            var relationshipManyToOne = entity1Metadata.ManyToOneRelationships.FirstOrDefault(r => r.SchemaName == linkDetails.RelationshipName);

            if (relationshipManyToOne != null)
            {
                relationshipMetadata.RelationshipType     = ProductAccessProvider.RelationshipType.ManyToOneRelationship;
                relationshipMetadata.ReferencedEntity     = relationshipManyToOne.ReferencedEntity;
                relationshipMetadata.ReferencingAttribute = relationshipManyToOne.ReferencingAttribute;
                relationshipMetadata.ReferencedAttribute  = relationshipManyToOne.ReferencedAttribute;
                return(relationshipMetadata);
            }

            var relationshipOneToMany = entity1Metadata.OneToManyRelationships.FirstOrDefault(r => r.SchemaName == linkDetails.RelationshipName);

            if (relationshipOneToMany != null)
            {
                relationshipMetadata.RelationshipType     = ProductAccessProvider.RelationshipType.OneToManyRelationship;
                relationshipMetadata.ReferencedEntity     = relationshipOneToMany.ReferencedEntity;
                relationshipMetadata.ReferencedAttribute  = relationshipOneToMany.ReferencedAttribute;
                relationshipMetadata.ReferencingAttribute = relationshipOneToMany.ReferencingAttribute;
                return(relationshipMetadata);
            }

            // This would be a failed case
            return(null);
        }
示例#2
0
        /// <summary>
        /// Modify a fetch and add necessary link entity elements and filter conditions to satisfy record level security trimming based on the relationship definitions.
        /// </summary>
        /// <param name="serviceContext"><see cref="OrganizationServiceContext"/> to use</param>
        /// <param name="relationshipMetadata">Relationship metadata that defines relationship attributes</param>
        /// <param name="linkDetails"><see cref="ContentAccessProvider.LinkDetails"/> to use</param>
        /// <param name="fetch">Fetch to modify</param>
        /// <param name="link">Link to construct</param>
        /// <param name="filter">Filter to construct</param>
        /// <param name="contact">Associated Contact</param>
        /// <param name="account">Associated Account</param>
        /// <param name="addCondition">Construct Account/Contact relationship filter</param>
        /// <param name="linkEntityAliasGenerator">LinkEntityAliasGenerator to track and create Aliases</param>
        private static void BuildLinksAndFilter(OrganizationServiceContext serviceContext, ProductAccessProvider.RelationshipMetadata relationshipMetadata, LinkDetails linkDetails, Fetch fetch, Link link, Filter filter, EntityReference contact, EntityReference account, bool addCondition, LinkEntityAliasGenerator linkEntityAliasGenerator)
        {
            var  alias   = linkEntityAliasGenerator.CreateUniqueAlias(relationshipMetadata.Entity2LogicalName);
            Link newLink = null;


            if (relationshipMetadata.RelationshipType == ProductAccessProvider.RelationshipType.ManyToManyRelationship)
            {
                var    intersectLinkEntityName = relationshipMetadata.IntersectEntityName;
                string linkTargetFromAttribute;
                string linkTargetToAttribute;
                string linkIntersectFromAttribute;
                string linkIntersectToAttribute;
                if (relationshipMetadata.Entity1LogicalName == relationshipMetadata.Entity2LogicalName)
                {
                    linkIntersectFromAttribute = relationshipMetadata.Entity2IntersectAttribute;
                    linkIntersectToAttribute   = relationshipMetadata.Entity1PrimaryIdAttribute;
                    linkTargetFromAttribute    = relationshipMetadata.Entity1PrimaryIdAttribute;
                    linkTargetToAttribute      = relationshipMetadata.Entity1IntersectAttribute;
                }
                else
                {
                    linkIntersectFromAttribute   =
                        linkIntersectToAttribute = relationshipMetadata.Entity1LogicalName == linkDetails.Entity1Name
                            ? relationshipMetadata.Entity1IntersectAttribute
                            : relationshipMetadata.Entity2IntersectAttribute;
                    linkTargetFromAttribute   =
                        linkTargetToAttribute = relationshipMetadata.Entity2LogicalName == linkDetails.Entity2Name
                            ? relationshipMetadata.Entity2IntersectAttribute
                            : relationshipMetadata.Entity1IntersectAttribute;
                }

                newLink = new Link
                {
                    Name          = intersectLinkEntityName,
                    FromAttribute = linkIntersectFromAttribute,
                    ToAttribute   = linkIntersectToAttribute,
                    Intersect     = true,
                    Visible       = false,
                    Type          = JoinOperator.LeftOuter,
                    Links         = new List <Link>
                    {
                        new Link
                        {
                            Name          = relationshipMetadata.Entity2LogicalName,
                            FromAttribute = linkTargetFromAttribute,
                            ToAttribute   = linkTargetToAttribute,
                            Alias         = alias,
                            Type          = JoinOperator.LeftOuter
                        }
                    }
                };
            }
            else if (relationshipMetadata.RelationshipType == ProductAccessProvider.RelationshipType.ManyToOneRelationship)
            {
                var linkFromAttribute = relationshipMetadata.ReferencedEntity == relationshipMetadata.Entity2LogicalName
                    ? relationshipMetadata.ReferencedAttribute
                    : relationshipMetadata.ReferencingAttribute;

                var linkToAttribute = relationshipMetadata.ReferencedEntity == relationshipMetadata.Entity2LogicalName
                    ? relationshipMetadata.ReferencingAttribute
                    : relationshipMetadata.ReferencedAttribute;

                newLink = new Link
                {
                    Name          = relationshipMetadata.Entity2LogicalName,
                    FromAttribute = linkFromAttribute,
                    ToAttribute   = linkToAttribute,
                    Type          = JoinOperator.LeftOuter,
                    Alias         = alias
                };
            }
            else if (relationshipMetadata.RelationshipType == ProductAccessProvider.RelationshipType.OneToManyRelationship)
            {
                var linkFromAttribute = relationshipMetadata.ReferencedEntity == relationshipMetadata.Entity2LogicalName
                    ? relationshipMetadata.ReferencedAttribute
                    : relationshipMetadata.ReferencingAttribute;

                var linkToAttribute = relationshipMetadata.ReferencedEntity == relationshipMetadata.Entity2LogicalName
                    ? relationshipMetadata.ReferencingAttribute
                    : relationshipMetadata.ReferencedAttribute;

                newLink = new Link
                {
                    Name          = relationshipMetadata.Entity2LogicalName,
                    FromAttribute = linkFromAttribute,
                    ToAttribute   = linkToAttribute,
                    Type          = JoinOperator.LeftOuter,
                    Alias         = alias
                };
            }
            else
            {
                throw new ApplicationException(string.Format("Retrieve relationship request failed for relationship name {0}", linkDetails.RelationshipName));
            }

            ContentAccessProvider.AddLink(link, newLink);


            if (addCondition) // Only add the condition if we are at the end of the chain
            {
                var condition = new Condition {
                    Attribute = relationshipMetadata.Entity2PrimaryIdAttribute
                };

                if (linkDetails.Scope.HasValue && linkDetails.Scope.Value == OwningCustomerType.Contact)
                {
                    condition.EntityName = alias;
                    condition.Operator   = ConditionOperator.Equal;
                    condition.Value      = contact.Id;
                }
                else if (linkDetails.Scope.HasValue && linkDetails.Scope.Value == OwningCustomerType.Account)
                {
                    condition.EntityName = alias;
                    condition.Operator   = ConditionOperator.Equal;
                    condition.Value      = account.Id;
                }
                else
                {
                    condition.EntityName = alias;
                    condition.Operator   = ConditionOperator.NotNull;
                }

                filter.Conditions.Add(condition);
            }

            fetch.Distinct = true;
        }