Example #1
0
        /// <summary>
        /// Declares 'relationship' members for a type.
        /// That is, all forward or reverse relationships that can connect to this type at one end or the other.
        /// </summary>
        /// <param name="entityType">The type entity.</param>
        /// <param name="memberGroup">The XSD container that will hold the members.</param>
        private void AddTypeRelationships(EffectiveType entityType, XmlSchemaGroupBase memberGroup)
        {
            // Define relationships applicable to type
            // This is defining that a given relationship container can appear under a resource of a particular type
            // e.g. <xs:element ref="worksFor" minOccurs="0" maxOccurs="1"/>
            // Note: maxOccurs refers to the relationship container, not the cardinality of the relationship itself.

            var relationships =
                from type in _schemaManager.GetAncestors(entityType.Type)
                from relationshipDefn in _schemaManager.GetRelationshipsToEntity(type, A(Aliases.FromType))
                select new { Relationship = relationshipDefn, Alias = relationshipDefn.Alias };

            var relationshipsRev =
                from type in _schemaManager.GetAncestors(entityType.Type)
                from relationshipDefn in _schemaManager.GetRelationshipsToEntity(type, A(Aliases.ToType))
                select new { Relationship = relationshipDefn, Alias = relationshipDefn.ReverseAlias };

            HashSet <XmlQualifiedName> hash = new HashSet <XmlQualifiedName>();

            foreach (var rel in relationships.Concat(relationshipsRev))
            {
                if (rel.Alias == null || string.IsNullOrEmpty(rel.Alias.Value))
                {
                    continue;
                }
                var fieldElem = new XmlSchemaElement();
                fieldElem.MaxOccurs = 1;    // the relationship container, not the relationships themselves
                fieldElem.MinOccurs = 0;
                fieldElem.RefName   = NameUsed(rel.Alias.ToQualifiedName());
                if (hash.Contains(fieldElem.RefName))
                {
                    throw new Exception("Already used: " + fieldElem.RefName.ToString());   // note: this can also get triggered if an inline-relationship defines a fromType node.
                }
                hash.Add(fieldElem.RefName);
                memberGroup.Items.Add(fieldElem);
            }
        }