Пример #1
0
        /// <summary>
        /// Create a foreign key constraint on two tables.
        /// </summary>
        /// <param name="dataModelSchema">The parent data model schema.</param>
        /// <param name="xmlSchemaKeyref">The XmlSchema object that describes the foreignn key relation.</param>
        public RelationSchema(DataModelSchema dataModelSchema, XmlSchemaKeyref xmlSchemaKeyref)
        {
            // Initialize the object.
            this.name = xmlSchemaKeyref.Name;

            // This will search through each of the tables looking for the parent and child components of the relation.
            foreach (KeyValuePair <string, TableSchema> keyValuePair in dataModelSchema.Tables)
            {
                ConstraintSchema constraintSchema;

                // This is the parent component of the relation.
                if (keyValuePair.Value.Constraints.TryGetValue(xmlSchemaKeyref.Refer.Name, out constraintSchema))
                {
                    UniqueConstraintSchema uniqueConstraintSchema = constraintSchema as UniqueConstraintSchema;
                    this.parentColumns       = uniqueConstraintSchema.Columns;
                    this.parentTable         = uniqueConstraintSchema.Table;
                    this.parentKeyConstraint = uniqueConstraintSchema;
                }

                // This is the child part of the relation.
                if (keyValuePair.Value.Constraints.TryGetValue(xmlSchemaKeyref.Name, out constraintSchema))
                {
                    ForeignKeyConstraintSchema foreignKeyConstraintSchema = constraintSchema as ForeignKeyConstraintSchema;
                    this.childTable         = foreignKeyConstraintSchema.Table;
                    this.childColumns       = foreignKeyConstraintSchema.Columns;
                    this.childKeyConstraint = foreignKeyConstraintSchema;
                }
            }
        }
Пример #2
0
        /// <summary>
        /// The foreign constraints can only be evaluated after all the tables, keys and unique constraints have been evaluated.
        /// </summary>
        /// <param name="xmlSchema"></param>
        private void SecondPass(XmlSchemaSet xmlSchemaSet)
        {
            // This is the second pass through the schemas.  Once the tables, keys and unique constraints have been evaluated,
            // then the foreign constraints can be constructed and applied to the parent and child tables.
            foreach (XmlSchemaElement xmlSchemaElement in xmlSchemaSet.GlobalElements.Values)
            {
                // Only the Microsoft DataSet element is evaluated for foreign keys.
                if (ObjectSchema.IsDataSetElement(xmlSchemaElement))
                {
                    // This will examine each of the constraints looking for a foreign key description.
                    foreach (XmlSchemaIdentityConstraint xmlSchemaIdentityConstraint in xmlSchemaElement.Constraints)
                    {
                        // Evaluate the foreign keys in the data model.
                        if (xmlSchemaIdentityConstraint is XmlSchemaKeyref)
                        {
                            // This object can be used as a foreign key constraint and, optionally, can be used to describe a
                            // parent/child relationship.
                            XmlSchemaKeyref xmlSchemaKeyref = xmlSchemaIdentityConstraint as XmlSchemaKeyref;

                            // This creates a foreign key.
                            ForeignKeyConstraintSchema foreignKeyConstraintSchema = new ForeignKeyConstraintSchema(this, xmlSchemaIdentityConstraint as XmlSchemaKeyref);

                            // Foreign constraint schemas are always added to the list of constraints on a table.  They can also
                            // conditionally become the source for a relationship between two tables.
                            foreignKeyConstraintSchema.Table.Add(foreignKeyConstraintSchema);

                            // Unless specifically instructed to supress the relation, it will be created add added to both the
                            // parent and child tables as well as the data model.
                            XmlAttribute isConstraintOnlyAttribute = ObjectSchema.GetUnhandledAttribute(xmlSchemaIdentityConstraint, QualifiedName.ConstraintOnly);
                            if (isConstraintOnlyAttribute == null || !Convert.ToBoolean(isConstraintOnlyAttribute.Value))
                            {
                                RelationSchema relationSchema = new RelationSchema(this, xmlSchemaKeyref);
                                relationSchema.ParentTable.ChildRelations.Add(relationSchema.Name, relationSchema);
                                relationSchema.ChildTable.ParentRelations.Add(relationSchema.Name, relationSchema);
                                this.Relations.Add(relationSchema.Name, relationSchema);
                            }
                        }
                    }
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Creates the element that describes a foreign constraint.
        /// </summary>
        /// <param name="foreignConstraintSchema">A description of a foreign constraint.</param>
        /// <returns>An element that can be used in an XML Schema document to describe a foreign constraint.</returns>
        private static XElement CreateForeignKey(ForeignKeyConstraintSchema foreignKeyConstraintSchema)
        {
            //    <xs:keyref name="FK_Entity_AccessControl" refer="EntityKey" msprop:rel_Generator_UserRelationName="FK_Entity_AccessControl"
            //		msprop:rel_Generator_RelationVarName="relationFK_Entity_AccessControl" msprop:rel_Generator_UserChildTable="AccessControl"
            //		msprop:rel_Generator_UserParentTable="Entity" msprop:rel_Generator_ParentPropName="EntityRow"
            //		msprop:rel_Generator_ChildPropName="GetAccessControlRows">
            //      <xs:selector xpath=".//mstns:AccessControl" />
            //      <xs:field xpath="mstns:EntityId" />
            //    </xs:keyref>
            XElement foreignElement = new XElement(
                SchemaScrubber.xs + "keyref",
                new XAttribute("name", foreignKeyConstraintSchema.Name),
                new XAttribute("refer", foreignKeyConstraintSchema.RelatedTable.GetUniqueConstraint(foreignKeyConstraintSchema.RelatedColumns).Name),
                new XAttribute(SchemaScrubber.msprop + "rel_Generator_UserRelationName", foreignKeyConstraintSchema.Name),
                new XAttribute(SchemaScrubber.msprop + "rel_Generator_RelationVarName", String.Format("relation{0}", foreignKeyConstraintSchema.Name)),
                new XAttribute(SchemaScrubber.msprop + "rel_Generator_UserChildTable", foreignKeyConstraintSchema.Table.Name),
                new XAttribute(SchemaScrubber.msprop + "rel_Generator_UserParentTable", foreignKeyConstraintSchema.RelatedTable.Name),
                new XAttribute(SchemaScrubber.msprop + "rel_Generator_ParentPropName", String.Format("{0}Row", foreignKeyConstraintSchema.RelatedTable.Name)),
                new XAttribute(SchemaScrubber.msprop + "rel_Generator_ChildPropName", String.Format("Get{0}Rows", foreignKeyConstraintSchema.Table.Name)));

            foreignElement.Add(
                new XElement(
                    SchemaScrubber.xs + "selector",
                    new XAttribute("xpath", String.Format(".//mstns:{0}", foreignKeyConstraintSchema.Table.Name))));

            foreach (ColumnSchema columnSchema in foreignKeyConstraintSchema.Columns)
            {
                foreignElement.Add(
                    new XElement(
                        SchemaScrubber.xs + "field",
                        new XAttribute("xpath", String.Format("mstns:{0}", columnSchema.Name))));
            }

            // This describes a foreign constraint on a table.
            return(foreignElement);
        }