/// <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); } }