예제 #1
0
        /// <summary>
        /// Generate XSD schema info for relationships.
        /// Specifically, register a named complexTyped, which can be referred to from entity types that are valid endpoints.
        /// </summary>
        private void AddRelationships()
        {
            // Note: both of either explicit relationship instances, or direct instances of the foreign type, can be embedded here.
            // However due to XSD limitations, the former must appear before the latter in the XML files.

            // E.g.
            //  <xs:element name="fieldIsOnType">
            //    <xs:complexType mixed="true">
            //      <xs:sequence>
            //        <xs:element minOccurs="0" maxOccurs="unbounded" ref="fieldIsOnType.instance" />
            //        <xs:group minOccurs="0" maxOccurs="unbounded" ref="is_type" />
            //      <xs:sequence>
            //    </xs:complexType>
            //  </xs:element>

            var relationships = EffectiveRelationships(_schemaManager.GetInstancesOfType(A(Aliases.Relationship)));

            // Prefetch the cardinality enum values

            foreach (EffectiveRelationship relationship in relationships)
            {
                XmlSchema xsd = GetSchema(relationship.Alias.Namespace);

                // Provide for explicit relationships instances that specify from/to
                AddRelationshipInstanceElement(relationship, xsd);

                if (relationship.IsSingleEnum)
                {
                    AddEnumValues(relationship);
                    continue;
                }

                // Get expected child type
                Entity toType;
                if (relationship.IsReverseAlias)
                {
                    toType = _schemaManager.GetRelationshipFromType(relationship.Type);
                }
                else
                {
                    toType = _schemaManager.GetRelationshipToType(relationship.Type);
                }

                // Determine cardinality
                var cardinality = _schemaManager.GetCardinality(relationship.Type);

                bool isBounded =
                    cardinality == Aliases.OneToOne ||
                    cardinality == Aliases.ManyToOne && !relationship.IsReverseAlias ||
                    cardinality == Aliases.OneToMany && relationship.IsReverseAlias;

                string maxOccurs = isBounded ? "1" : "unbounded";

                // Build XSD
                var sequence = new XmlSchemaSequence();
                sequence.Items.Add(new XmlSchemaGroupRef()
                {
                    RefName         = NameUsed(toType.Alias.ToQualifiedName("is_", null)),
                    MinOccurs       = 0,
                    MaxOccursString = maxOccurs
                });
                var complexType = new XmlSchemaComplexType()
                {
                    IsMixed  = true,
                    Particle = sequence
                };

                var relElement = new XmlSchemaElement();
                relElement.Name       = NameDeclared(relationship.Alias.Value, relationship.Alias.Namespace);
                relElement.SchemaType = complexType;

                // Add to schema
                xsd.Items.Add(relElement);
            }
        }