示例#1
0
        internal void UpdateSsdl(XmlDocument ssdlDocument, TableMappingCollection tableMappings)
        {
            foreach (ScalarProperty property in this.ScalarProperties)
            {
                property.UpdateSsdl(ssdlDocument, tableMappings);
            }


            #region Create CUD Functions.
            XmlNamespaceManager nsMgr = new XmlNamespaceManager(ssdlDocument.NameTable);
            nsMgr.AddNamespace(CoreResources.SSDLNamespacePrefix,
                               CoreResources.SSDLSchemaNameSpace);
            XmlElement schemaElement = ssdlDocument.SelectSingleNode(
                CoreResources.XPathSSDLSchema, nsMgr) as XmlElement;

            List <string> parameters       = new List <string>();
            List <string> deleteParameters = new List <string>();
            deleteParameters.Add(CoreResources.Id);
            deleteParameters.Add(CoreResources.DataTypeUniqueidentifier);
            deleteParameters.Add(CoreResources.In);

            ResourceType tempType = this;
            while (tempType != null)
            {
                foreach (ScalarProperty scalarProperty in tempType.ScalarProperties)
                {
                    parameters.Add(scalarProperty.Name);
                    parameters.Add(Utilities.GetSQLType(scalarProperty.DataType));
                    parameters.Add(CoreResources.In);
                }
                foreach (NavigationProperty navigationProperty in tempType.NavigationProperties)
                {
                    if (tableMappings.GetColumnMappingByPropertyId(navigationProperty.Id) != null)
                    {
                        parameters.Add(navigationProperty.Name);
                        parameters.Add(CoreResources.DataTypeUniqueidentifier);
                        parameters.Add(CoreResources.In);

                        deleteParameters.Add(navigationProperty.Name);
                        deleteParameters.Add(CoreResources.DataTypeUniqueidentifier);
                        deleteParameters.Add(CoreResources.In);
                    }
                }
                tempType = tempType.BaseType;
            }

            Utilities.AddSsdlFunction(schemaElement, this.InsertProcedureName, false, false,
                                      false, false, CoreResources.AllowImplicitConversion, CoreResources.Core,
                                      parameters.ToArray());

            Utilities.AddSsdlFunction(schemaElement, this.UpdateProcedureName, false, false,
                                      false, false, CoreResources.AllowImplicitConversion, CoreResources.Core,
                                      parameters.ToArray());

            Utilities.AddSsdlFunction(schemaElement, this.DeleteProcedureName, false, false, false,
                                      false, CoreResources.AllowImplicitConversion, CoreResources.Core,
                                      deleteParameters.ToArray());

            #endregion
        }
示例#2
0
        /// <summary>
        /// Updates the MSL.
        /// </summary>
        /// <param name="entityTypeMapping">The entity type mapping.</param>
        /// <param name="tableMappings">The table mappings.</param>
        /// <param name="discriminators">The discriminators.</param>
        internal void UpdateMsl(XmlElement entityTypeMapping, TableMappingCollection tableMappings, Dictionary <Guid, int> discriminators)
        {
            // Locate the table and column mappings for this property.
            ColumnMapping columnMapping = tableMappings.GetColumnMappingByPropertyId(this.Id);
            TableMapping  tableMapping  = columnMapping.Parent;

            string cachedTableName  = tableMapping.TableName;
            string cachedColumnName = columnMapping.ColumnName;

            // Locate or create <MappingFragment> element.
            XmlNamespaceManager nsMgr = new XmlNamespaceManager(
                entityTypeMapping.OwnerDocument.NameTable);

            nsMgr.AddNamespace(DataModellingResources.MSLNamespacePrefix, DataModellingResources.MSLSchemaNamespace);
            XmlNodeList mappingFragments = entityTypeMapping.SelectNodes(
                string.Format(CultureInfo.InvariantCulture, DataModellingResources.XPathMSLMappingFragment,
                              cachedTableName), nsMgr);
            XmlElement mappingFragment = null;

            if (mappingFragments.Count == 0)
            {
                mappingFragment = Utilities.CreateElement(entityTypeMapping,
                                                          DataModellingResources.MappingFragment);
                Utilities.AddAttribute(mappingFragment, DataModellingResources.StoreEntitySet, cachedTableName);

                // Add mapping for the Id column.
                XmlElement idMapping = Utilities.CreateElement(mappingFragment,
                                                               DataModellingResources.ScalarProperty);
                Utilities.AddAttribute(idMapping, DataModellingResources.Name, DataModellingResources.Id);
                Utilities.AddAttribute(idMapping, DataModellingResources.ColumnName, DataModellingResources.Id);

                // Add Condition element.
                XmlElement conditionElement = Utilities.CreateElement(mappingFragment,
                                                                      DataModellingResources.Condition);
                Utilities.AddAttribute(conditionElement, DataModellingResources.ColumnName,
                                       DataModellingResources.Discriminator);
                Utilities.AddAttribute(conditionElement, DataModellingResources.Value,
                                       discriminators[this.Parent.Id].ToString(CultureInfo.InvariantCulture).
                                       ToLowerInvariant());
            }
            else
            {
                mappingFragment = mappingFragments[0] as XmlElement;
            }

            // Create <ScalarProperty> element.
            XmlElement scalarProperty = Utilities.CreateElement(mappingFragment,
                                                                DataModellingResources.ScalarProperty);

            Utilities.AddAttribute(scalarProperty, DataModellingResources.Name, this.Name);
            Utilities.AddAttribute(scalarProperty, DataModellingResources.ColumnName, cachedColumnName);
        }
示例#3
0
        /// <summary>
        /// Updates the SSDL.
        /// </summary>
        /// <param name="ssdlDocument">The SSDL document.</param>
        /// <param name="tableMappings">The table mappings.</param>
        internal void UpdateSsdl(XmlDocument ssdlDocument, TableMappingCollection tableMappings)
        {
            // Locate the table and column mappings for this property.
            ColumnMapping columnMapping = tableMappings.GetColumnMappingByPropertyId(
                this.Id);
            TableMapping tableMapping = columnMapping.Parent;

            string cachedTableName  = tableMapping.TableName;
            string cachedColumnName = columnMapping.ColumnName;

            XmlNamespaceManager nsMgr = new XmlNamespaceManager(ssdlDocument.NameTable);

            nsMgr.AddNamespace(DataModellingResources.SSDLNamespacePrefix,
                               DataModellingResources.SSDLSchemaNameSpace);

            // Locate the Schema element.
            XmlElement schemaElement = ssdlDocument.SelectSingleNode(
                DataModellingResources.XPathSSDLSchema, nsMgr) as XmlElement;
            string storageSchemaNamespace = schemaElement.Attributes[DataModellingResources.Namespace].
                                            Value;
            string tableFullName =
                Utilities.MergeSubNames(storageSchemaNamespace, cachedTableName);

            // Locate the EntityType for this table.
            XmlElement entityContainerElement = ssdlDocument.SelectSingleNode(
                DataModellingResources.XPathSSDLEntityContainer, nsMgr) as XmlElement;
            XmlNodeList entityTypes = schemaElement.SelectNodes(string.Format(
                                                                    CultureInfo.InvariantCulture, DataModellingResources.XPathSSDLEntityType, cachedTableName),
                                                                nsMgr);
            XmlElement entityTypeElement = null;

            // If not found, create the EntitySet and the EntityType elements.
            // NOTE: We have added and FK from new table to Resource table. This is necessary
            // so that EF inserts entries in the correct order across multiple tables. For
            // example, let's say EntityA spans across 3 tables, Resource, Tab1 and Tab2. The
            // entity has a one-to-many association with itself. The FK column resides in Tab2.
            // Now let's say we create just one resource and associate it with itself. While
            // entering the details for this resource, if EF inserts values into Tab2 before
            // Resource, the foreign key constraint might fail.
            if (entityTypes.Count == 0)
            {
                // Create EntitySet element.
                Utilities.AddSsdlEntitySetForTables(entityContainerElement, cachedTableName, tableFullName,
                                                    DataModellingResources.Core);

                // Create AssociationSet element.
                string fkConstraintName = string.Format(CultureInfo.InvariantCulture,
                                                        DataModellingResources.FKConstraintName, cachedTableName);
                string fkConstraintFullName =
                    Utilities.MergeSubNames(storageSchemaNamespace, fkConstraintName);
                Utilities.AddSsdlAssociationSet(entityContainerElement, fkConstraintName,
                                                fkConstraintFullName, DataModellingResources.Resource, DataModellingResources.Resource,
                                                cachedTableName, cachedTableName);

                // Create EntityType element
                entityTypeElement = Utilities.AddSsdlEntityType(schemaElement, cachedTableName,
                                                                DataModellingResources.Id);

                // Add Id and Discriminator properties.
                Utilities.AddSsdlEntityTypeProperty(entityTypeElement, DataModellingResources.Id,
                                                    DataModellingResources.DataTypeUniqueidentifier, false);
                Utilities.AddSsdlEntityTypeProperty(entityTypeElement,
                                                    DataModellingResources.Discriminator, DataModellingResources.DataTypeInt, false);

                // Create Association element.
                Utilities.AddSsdlAssociation(schemaElement, fkConstraintName,
                                             DataModellingResources.Resource,
                                             Utilities.MergeSubNames(storageSchemaNamespace, DataModellingResources.Resource),
                                             DataModellingResources.One, cachedTableName,
                                             Utilities.MergeSubNames(storageSchemaNamespace, cachedTableName),
                                             DataModellingResources.ZeroOrOne,
                                             DataModellingResources.Resource, new string[] { DataModellingResources.Id }, cachedTableName,
                                             new string[] { DataModellingResources.Id });
            }
            else
            {
                entityTypeElement = entityTypes[0] as XmlElement;
            }

            // Add Name, ManagerType, Nullable and data type specific attributes.
            // NOTE: Nullable is always true in the SSDL. This is important for the TPH
            // type of mapping.
            if (this.DataType == DataTypes.String || this.DataType == DataTypes.Binary)
            {
                if (this.MaxLength < 0)
                {
                    Utilities.AddSsdlEntityTypeProperty(entityTypeElement, cachedColumnName,
                                                        Utilities.GetSQLType(this.DataType) +
                                                        string.Format(CultureInfo.InvariantCulture, DataModellingResources.Paranthesis,
                                                                      DataModellingResources.Max).ToLowerInvariant(),
                                                        true);
                }
                else
                {
                    Utilities.AddSsdlEntityTypeProperty(entityTypeElement, cachedColumnName,
                                                        Utilities.GetSQLType(this.DataType), true, this.MaxLength);
                }
            }
            else if (this.DataType == DataTypes.Decimal)
            {
                Utilities.AddSsdlEntityTypeProperty(entityTypeElement, cachedColumnName,
                                                    Utilities.GetSQLType(this.DataType), true, this.Precision, this.Scale);
            }
            else
            {
                Utilities.AddSsdlEntityTypeProperty(entityTypeElement, cachedColumnName,
                                                    Utilities.GetSQLType(this.DataType), true);
            }
        }
示例#4
0
        private static void UpdateSsdlHandleOneToXxxAssociations(XmlElement entityContainerElement, XmlElement schemaElement, Guid xxxSidePropertyId, TableMappingCollection tableMappings)
        {
            // Locate the table and column mappings for this property.
            ColumnMapping columnMapping = tableMappings.GetColumnMappingByPropertyId(
                xxxSidePropertyId);
            TableMapping tableMapping = columnMapping.Parent;

            string tableName              = tableMapping.TableName;
            string columnName             = columnMapping.ColumnName;
            string storageSchemaNamespace = schemaElement.Attributes[CoreResources.Namespace].
                                            Value;
            string tableFullName = Utilities.MergeSubNames(
                storageSchemaNamespace, tableName);

            // Locate the EntityType for this table.
            XmlNamespaceManager nsMgr = new XmlNamespaceManager(
                entityContainerElement.OwnerDocument.NameTable);

            nsMgr.AddNamespace(CoreResources.SSDLNamespacePrefix,
                               CoreResources.SSDLSchemaNameSpace);
            XmlNodeList entityTypes = schemaElement.SelectNodes(string.Format(
                                                                    CultureInfo.InvariantCulture, CoreResources.XPathSSDLEntityType, tableName),
                                                                nsMgr);
            XmlElement entityTypeElement = null;

            // If not found, create the EntitySet and the EntityType elements.
            // NOTE: We have added and FK from new table to Resource table. This is necessary
            // so that EF inserts entries in the correct order across multiple tables. For
            // example, let's say EntityA spans across 3 tables, Resource, Tab1 and Tab2. The
            // entity has a one-to-many association with itself. The FK column resides in Tab2.
            // Now let's say we create just one resource and associate it with itself. While
            // entering the details for this resource, if EF inserts values into Tab2 before
            // Resource, the foreign key constraint might fail.
            if (entityTypes.Count == 0)
            {
                // Create EntitySet element.
                Utilities.AddSsdlEntitySetForTables(entityContainerElement, tableName, tableFullName,
                                                    CoreResources.Core);

                // Create AssociationSet element.
                string fkConstraintName = string.Format(CultureInfo.InvariantCulture,
                                                        CoreResources.FKConstraintName, tableName);
                string fkConstraintFullName = Utilities.MergeSubNames(
                    storageSchemaNamespace, fkConstraintName);
                Utilities.AddSsdlAssociationSet(entityContainerElement, fkConstraintName,
                                                fkConstraintFullName, CoreResources.Resource, CoreResources.Resource,
                                                tableName, tableName);

                // Create EntityType element
                entityTypeElement = Utilities.AddSsdlEntityType(schemaElement, tableName,
                                                                CoreResources.Id);

                // Add Id and Discriminator properties.
                Utilities.AddSsdlEntityTypeProperty(entityTypeElement, CoreResources.Id,
                                                    CoreResources.DataTypeUniqueidentifier, false);
                Utilities.AddSsdlEntityTypeProperty(entityTypeElement,
                                                    CoreResources.Discriminator, CoreResources.DataTypeInt, false);

                // Create Association element.
                Utilities.AddSsdlAssociation(schemaElement, fkConstraintName,
                                             CoreResources.Resource, Utilities.MergeSubNames(
                                                 storageSchemaNamespace, CoreResources.Resource),
                                             CoreResources.One, tableName, tableFullName, CoreResources.ZeroOrOne,
                                             CoreResources.Resource, new string[] { CoreResources.Id }, tableName,
                                             new string[] { CoreResources.Id });
            }
            else
            {
                entityTypeElement = entityTypes[0] as XmlElement;
            }

            // Add the foreign key column to EntityType element. Take note that all
            // foreign key columns are nullable. This is necessary since the table
            // might also host rows for some other entity type and while inserting
            // rows for the other entity type, EF inserts NULL values for this entity
            // type.
            Utilities.AddSsdlEntityTypeProperty(entityTypeElement, columnName,
                                                CoreResources.DataTypeUniqueidentifier, true);

            // Add AssociationSet element for the foreign key. It is possible that the FK
            // column is hosted by Resource table. To create different roles, we use the
            // column name to distinguish between the roles.
            string associationFKConstraintName = string.Format(CultureInfo.InvariantCulture,
                                                               CoreResources.FKConstraintName, columnName);
            string associationFKConstraintFullName = Utilities.MergeSubNames(
                storageSchemaNamespace, associationFKConstraintName);

            Utilities.AddSsdlAssociationSet(entityContainerElement, associationFKConstraintName,
                                            associationFKConstraintFullName, CoreResources.Resource, CoreResources.Resource,
                                            columnName, tableName);

            // Add Association element.
            Utilities.AddSsdlAssociation(schemaElement, associationFKConstraintName,
                                         CoreResources.Resource, Utilities.MergeSubNames(
                                             storageSchemaNamespace, CoreResources.Resource),
                                         CoreResources.ZeroOrOne, columnName, tableFullName, CoreResources.Many,
                                         CoreResources.Resource, new string[] { CoreResources.Id }, columnName,
                                         new string[] { columnName });
        }
示例#5
0
        internal void UpdateMsl(XmlDocument mslDocument, TableMappingCollection tableMappings, string storageSchemaName)
        {
            // Locate the EntityContainer element.
            XmlNamespaceManager nsMgr = new XmlNamespaceManager(mslDocument.NameTable);

            nsMgr.AddNamespace(CoreResources.MSLNamespacePrefix, CoreResources.MSLSchemaNamespace);

            XmlElement entityContainerMappingElement = mslDocument.SelectSingleNode(
                CoreResources.XPathMSLEntityContainerMapping, nsMgr) as XmlElement;

            // We don't support One to One associations.
            if (this.SubjectMultiplicity == AssociationEndMultiplicity.One &&
                this.ObjectMultiplicity == AssociationEndMultiplicity.One)
            {
                throw new ZentityException(CoreResources.InvalidMultiplicityOneToOne);
            }

            // Handle view mappings.
            else if (this.SubjectMultiplicity == AssociationEndMultiplicity.Many &&
                     this.ObjectMultiplicity == AssociationEndMultiplicity.Many ||
                     this.SubjectMultiplicity == AssociationEndMultiplicity.Many &&
                     this.ObjectMultiplicity == AssociationEndMultiplicity.ZeroOrOne ||
                     this.SubjectMultiplicity == AssociationEndMultiplicity.ZeroOrOne &&
                     this.ObjectMultiplicity == AssociationEndMultiplicity.Many ||
                     this.SubjectMultiplicity == AssociationEndMultiplicity.ZeroOrOne &&
                     this.ObjectMultiplicity == AssociationEndMultiplicity.ZeroOrOne)
            {
                // Create FunctionImportMapping elements.
                string createFunctionFullName = Utilities.MergeSubNames(
                    storageSchemaName, InsertProcedureName);
                string deleteFunctionFullName = Utilities.MergeSubNames(
                    storageSchemaName, DeleteProcedureName);

                Utilities.AddMslFunctionImportMapping(entityContainerMappingElement,
                                                      InsertProcedureName, createFunctionFullName);

                Utilities.AddMslFunctionImportMapping(entityContainerMappingElement,
                                                      DeleteProcedureName, deleteFunctionFullName);

                // Create AssociationSetMapping element.
                UpdateMslCreateAssociationSetMappingElement(entityContainerMappingElement, this.Name,
                                                            this.FullName, this.ViewName, this.SubjectRole, CoreResources.Id,
                                                            CoreResources.SubjectResourceId, this.ObjectRole, CoreResources.Id,
                                                            CoreResources.ObjectResourceId, createFunctionFullName, deleteFunctionFullName,
                                                            CoreResources.SubjectResourceId, CoreResources.ObjectResourceId);
            }

            else
            {
                ColumnMapping columnMapping = null;
                XmlElement    associationSetMappingElement = null;

                // Handle OneToXXX mappings except One to One.
                if (this.SubjectMultiplicity == AssociationEndMultiplicity.One)
                {
                    columnMapping = tableMappings.GetColumnMappingByPropertyId(
                        this.ObjectNavigationProperty.Id);

                    associationSetMappingElement = UpdateMslCreateAssociationSetMappingElement(
                        entityContainerMappingElement, this.Name, this.FullName,
                        columnMapping.Parent.TableName, this.SubjectRole, CoreResources.Id,
                        columnMapping.ColumnName, this.ObjectRole, CoreResources.Id,
                        CoreResources.Id);
                }
                // Handle XXXToOne mappings except One to One.
                else
                {
                    columnMapping = tableMappings.GetColumnMappingByPropertyId(
                        this.SubjectNavigationProperty.Id);

                    associationSetMappingElement = UpdateMslCreateAssociationSetMappingElement(
                        entityContainerMappingElement, this.Name, this.FullName,
                        columnMapping.Parent.TableName, this.SubjectRole, CoreResources.Id,
                        CoreResources.Id, this.ObjectRole, CoreResources.Id,
                        columnMapping.ColumnName);
                }

                // Add the NOT NULL Condition element for foreign key column.
                XmlElement conditionElement = Utilities.CreateElement(associationSetMappingElement,
                                                                      CoreResources.Condition);
                Utilities.AddAttribute(conditionElement, CoreResources.ColumnName,
                                       columnMapping.ColumnName);
                Utilities.AddAttribute(conditionElement, CoreResources.IsNull,
                                       false.ToString().ToLowerInvariant());
            }
        }