コード例 #1
0
        private static EdmFunction ConvertToFunction(
            Som.Function somFunction,
            DbProviderManifest providerManifest,
            ConversionCache convertedItemCache,
            EntityContainer functionImportEntityContainer,
            Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems)
        {
            // If we already have it, don't bother converting
            GlobalItem globalItem = null;

            // if we are converted the function import, we need not check the global items collection,
            // since the function imports are local to the entity container
            if (!somFunction.IsFunctionImport
                && newGlobalItems.TryGetValue(somFunction, out globalItem))
            {
                return (EdmFunction)globalItem;
            }

            var areConvertingForProviderManifest = somFunction.Schema.DataModel == Som.SchemaDataModelOption.ProviderManifestModel;
            var returnParameters = new List<FunctionParameter>();
            if (somFunction.ReturnTypeList != null)
            {
                var i = 0;
                foreach (var somReturnType in somFunction.ReturnTypeList)
                {
                    var returnType = GetFunctionTypeUsage(
                        somFunction is Som.ModelFunction,
                        somFunction,
                        somReturnType,
                        providerManifest,
                        areConvertingForProviderManifest,
                        somReturnType.Type,
                        somReturnType.CollectionKind,
                        somReturnType.IsRefType /*isRefType*/,
                        convertedItemCache,
                        newGlobalItems);
                    if (null != returnType)
                    {
                        // Create the return parameter object, need to set the declaring type explicitly on the return parameter
                        // because we aren't adding it to the members collection
                        var modifier = i == 0 ? string.Empty : i.ToString(CultureInfo.InvariantCulture);
                        i++;
                        var returnParameter = new FunctionParameter(
                            EdmConstants.ReturnType + modifier, returnType, ParameterMode.ReturnValue);
                        AddOtherContent(somReturnType, returnParameter);
                        returnParameters.Add(returnParameter);
                    }
                    else
                    {
                        return null;
                    }
                }
            }
                // this case must be second to avoid calling somFunction.Type when returnTypeList has more than one element.
            else if (somFunction.Type != null)
            {
                var returnType = GetFunctionTypeUsage(
                    somFunction is Som.ModelFunction,
                    somFunction,
                    null,
                    providerManifest,
                    areConvertingForProviderManifest,
                    somFunction.Type,
                    somFunction.CollectionKind,
                    somFunction.IsReturnAttributeReftype /*isRefType*/,
                    convertedItemCache,
                    newGlobalItems);
                if (null != returnType)
                {
                    // Create the return parameter object, need to set the declaring type explicitly on the return parameter
                    // because we aren't adding it to the members collection                    
                    returnParameters.Add(new FunctionParameter(EdmConstants.ReturnType, returnType, ParameterMode.ReturnValue));
                }
                else
                {
                    //Return type was specified but we could not find a type usage
                    return null;
                }
            }

            string functionNamespace;
            EntitySet[] entitySets = null;
            if (somFunction.IsFunctionImport)
            {
                var somFunctionImport = (Som.FunctionImportElement)somFunction;
                functionNamespace = somFunctionImport.Container.Name;
                if (null != somFunctionImport.EntitySet)
                {
                    EntityContainer entityContainer;
                    Debug.Assert(
                        somFunctionImport.ReturnTypeList == null || somFunctionImport.ReturnTypeList.Count == 1,
                        "EntitySet cannot be specified on a FunctionImport if there are multiple ReturnType children");

                    Debug.Assert(
                        functionImportEntityContainer != null,
                        "functionImportEntityContainer must be specified during function import conversion");
                    entityContainer = functionImportEntityContainer;
                    entitySets = new[] { GetEntitySet(somFunctionImport.EntitySet, entityContainer) };
                }
                else if (null != somFunctionImport.ReturnTypeList)
                {
                    Debug.Assert(
                        functionImportEntityContainer != null,
                        "functionImportEntityContainer must be specified during function import conversion");
                    var entityContainer = functionImportEntityContainer;
                    entitySets = somFunctionImport.ReturnTypeList
                        .Select(
                            returnType => null != returnType.EntitySet
                                              ? GetEntitySet(returnType.EntitySet, functionImportEntityContainer)
                                              : null)
                        .ToArray();
                }
            }
            else
            {
                functionNamespace = somFunction.Namespace;
            }

            var parameters = new List<FunctionParameter>();
            foreach (var somParameter in somFunction.Parameters)
            {
                var parameterType = GetFunctionTypeUsage(
                    somFunction is Som.ModelFunction,
                    somFunction,
                    somParameter,
                    providerManifest,
                    areConvertingForProviderManifest,
                    somParameter.Type,
                    somParameter.CollectionKind,
                    somParameter.IsRefType,
                    convertedItemCache,
                    newGlobalItems);
                if (parameterType == null)
                {
                    return null;
                }

                var parameter = new FunctionParameter(
                    somParameter.Name,
                    parameterType,
                    GetParameterMode(somParameter.ParameterDirection));
                AddOtherContent(somParameter, parameter);

                if (somParameter.Documentation != null)
                {
                    parameter.Documentation = ConvertToDocumentation(somParameter.Documentation);
                }
                parameters.Add(parameter);
            }

            var function = new EdmFunction(
                somFunction.Name,
                functionNamespace,
                GetDataSpace(providerManifest),
                new EdmFunctionPayload
                    {
                        Schema = somFunction.DbSchema,
                        StoreFunctionName = somFunction.StoreFunctionName,
                        CommandText = somFunction.CommandText,
                        EntitySets = entitySets,
                        IsAggregate = somFunction.IsAggregate,
                        IsBuiltIn = somFunction.IsBuiltIn,
                        IsNiladic = somFunction.IsNiladicFunction,
                        IsComposable = somFunction.IsComposable,
                        IsFromProviderManifest = areConvertingForProviderManifest,
                        IsFunctionImport = somFunction.IsFunctionImport,
                        ReturnParameters = returnParameters.ToArray(),
                        Parameters = parameters.ToArray(),
                        ParameterTypeSemantics = somFunction.ParameterTypeSemantics,
                    });

            // Add this function to new global items, only if it is not a function import
            if (!somFunction.IsFunctionImport)
            {
                newGlobalItems.Add(somFunction, function);
            }

            //Check if we already converted functions since we are loading it from 
            //ssdl we could see functions many times.
            GlobalItem returnFunction = null;
            Debug.Assert(
                !convertedItemCache.ItemCollection.TryGetValue(function.Identity, false, out returnFunction),
                "Function duplicates must be checked by som");

            // Extract the optional Documentation
            if (somFunction.Documentation != null)
            {
                function.Documentation = ConvertToDocumentation(somFunction.Documentation);
            }
            AddOtherContent(somFunction, function);

            return function;
        }
コード例 #2
0
        /// <summary>
        /// Converts a property from SOM to metadata
        /// </summary>
        /// <param name="somProperty">The SOM element to process</param>
        /// <param name="providerManifest">The provider manifest to be used for conversion</param>
        /// <param name="convertedItemCache">The item collection for currently existing metadata objects</param>
        /// <param name="newGlobalItems">The new GlobalItem objects that are created as a result of this conversion</param>
        /// <returns>The property object resulting from the convert</returns>
        private static EdmProperty ConvertToProperty(
            Som.StructuredProperty somProperty,
            DbProviderManifest providerManifest,
            ConversionCache convertedItemCache,
            Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems)
        {
            EdmProperty property;

            // Get the appropriate type object for this type, for primitive and enum types, get the facet values for the type
            // property as a type usage object as well                  
            TypeUsage typeUsage = null;

            var scalarType = somProperty.Type as Som.ScalarType;

            if (scalarType != null
                && somProperty.Schema.DataModel != Som.SchemaDataModelOption.EntityDataModel)
            {
                // parsing ssdl
                typeUsage = somProperty.TypeUsage;
                UpdateSentinelValuesInFacets(ref typeUsage);
            }
            else
            {
                EdmType propertyType;

                if (scalarType != null)
                {
                    Debug.Assert(somProperty.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType);
                    // try to get the instance of the primitive type from the item collection so that it back pointer is set.
                    propertyType = convertedItemCache.ItemCollection.GetItem<PrimitiveType>(somProperty.TypeUsage.EdmType.FullName);
                }
                else
                {
                    propertyType = (EdmType)LoadSchemaElement(somProperty.Type, providerManifest, convertedItemCache, newGlobalItems);
                }

                if (somProperty.CollectionKind
                    != CollectionKind.None)
                {
                    typeUsage = TypeUsage.Create(new CollectionType(propertyType));
                }
                else
                {
                    var enumType = scalarType == null ? somProperty.Type as Som.SchemaEnumType : null;
                    typeUsage = TypeUsage.Create(propertyType);
                    if (enumType != null)
                    {
                        somProperty.EnsureEnumTypeFacets(convertedItemCache, newGlobalItems);
                    }

                    if (somProperty.TypeUsage != null)
                    {
                        ApplyTypePropertyFacets(somProperty.TypeUsage, ref typeUsage);
                    }
                }
            }

            PopulateGeneralFacets(somProperty, ref typeUsage);
            property = new EdmProperty(somProperty.Name, typeUsage);

            // Extract the optional Documentation
            if (somProperty.Documentation != null)
            {
                property.Documentation = ConvertToDocumentation(somProperty.Documentation);
            }
            AddOtherContent(somProperty, property);

            return property;
        }
コード例 #3
0
        /// <summary>
        /// Converts a navigation property from SOM to metadata
        /// </summary>
        /// <param name="declaringEntityType">entity type on which this navigation property was declared</param>
        /// <param name="somNavigationProperty">The SOM element to process</param>
        /// <param name="providerManifest">The provider manifest to be used for conversion</param>
        /// <param name="convertedItemCache">The item collection for currently existing metadata objects</param>
        /// <param name="newGlobalItems">The new GlobalItem objects that are created as a result of this conversion</param>
        /// <returns>The property object resulting from the convert</returns>
        private static NavigationProperty ConvertToNavigationProperty(
            EntityType declaringEntityType,
            Som.NavigationProperty somNavigationProperty,
            DbProviderManifest providerManifest,
            ConversionCache convertedItemCache,
            Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems)
        {
            // Navigation properties cannot be primitive types, so we can ignore the possibility of having primitive type
            // facets
            var toEndEntityType = (EntityType)LoadSchemaElement(
                somNavigationProperty.Type,
                providerManifest,
                convertedItemCache,
                newGlobalItems);

            EdmType edmType = toEndEntityType;

            // Also load the relationship Type that this navigation property represents
            var relationshipType = (AssociationType)LoadSchemaElement(
                (Som.Relationship)somNavigationProperty.Relationship,
                providerManifest, convertedItemCache, newGlobalItems);

            Som.IRelationshipEnd somRelationshipEnd = null;
            somNavigationProperty.Relationship.TryGetEnd(somNavigationProperty.ToEnd.Name, out somRelationshipEnd);
            if (somRelationshipEnd.Multiplicity
                == RelationshipMultiplicity.Many)
            {
                edmType = toEndEntityType.GetCollectionType();
            }
            else
            {
                Debug.Assert(somRelationshipEnd.Multiplicity != RelationshipMultiplicity.Many);
                edmType = toEndEntityType;
            }

            TypeUsage typeUsage;
            if (somRelationshipEnd.Multiplicity
                == RelationshipMultiplicity.One)
            {
                typeUsage = TypeUsage.Create(
                    edmType,
                    new FacetValues
                        {
                            Nullable = false
                        });
            }
            else
            {
                typeUsage = TypeUsage.Create(edmType);
            }

            // We need to make sure that both the ends of the relationtype are initialized. If there are not, then we should
            // initialize them here
            InitializeAssociationEndMember(relationshipType, somNavigationProperty.ToEnd, toEndEntityType);
            InitializeAssociationEndMember(relationshipType, somNavigationProperty.FromEnd, declaringEntityType);

            // The type of the navigation property must be a ref or collection depending on which end they belong to
            var navigationProperty = new NavigationProperty(somNavigationProperty.Name, typeUsage);
            navigationProperty.RelationshipType = relationshipType;
            navigationProperty.ToEndMember = (RelationshipEndMember)relationshipType.Members[somNavigationProperty.ToEnd.Name];
            navigationProperty.FromEndMember = (RelationshipEndMember)relationshipType.Members[somNavigationProperty.FromEnd.Name];

            // Extract the optional Documentation
            if (somNavigationProperty.Documentation != null)
            {
                navigationProperty.Documentation = ConvertToDocumentation(somNavigationProperty.Documentation);
            }
            AddOtherContent(somNavigationProperty, navigationProperty);

            return navigationProperty;
        }
コード例 #4
0
        /// <summary>
        /// Converts an entity set from SOM to metadata
        /// </summary>
        /// <param name="set">The SOM element to process</param>
        /// <param name="providerManifest">The provider manifest to be used for conversion</param>
        /// <param name="convertedItemCache">The item collection for currently existing metadata objects</param>
        /// <param name="newGlobalItems">The new GlobalItem objects that are created as a result of this conversion</param>
        /// <returns>The entity set object resulting from the convert</returns>
        private static EntitySet ConvertToEntitySet(
            Som.EntityContainerEntitySet set,
            DbProviderManifest providerManifest,
            ConversionCache convertedItemCache,
            Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems)
        {
            var entitySet = new EntitySet(
                set.Name, set.DbSchema, set.Table, set.DefiningQuery,
                (EntityType)LoadSchemaElement(
                    set.EntityType,
                    providerManifest,
                    convertedItemCache,
                    newGlobalItems));

            // Extract the optional Documentation
            if (set.Documentation != null)
            {
                entitySet.Documentation = ConvertToDocumentation(set.Documentation);
            }
            AddOtherContent(set, entitySet);

            return entitySet;
        }
コード例 #5
0
        /// <summary>
        /// Converts an association set from SOM to metadata
        /// </summary>
        /// <param name="relationshipSet">The SOM element to process</param>
        /// <param name="providerManifest">The provider manifest to be used for conversion</param>
        /// <param name="convertedItemCache">The item collection for currently existing metadata objects</param>
        /// <param name="newGlobalItems">The new GlobalItem objects that are created as a result of this conversion</param>
        /// <param name="container"></param>
        /// <returns>The association set object resulting from the convert</returns>
        private static AssociationSet ConvertToAssociationSet(
            Som.EntityContainerRelationshipSet relationshipSet,
            DbProviderManifest providerManifest,
            ConversionCache convertedItemCache,
            EntityContainer container,
            Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems)
        {
            Debug.Assert(relationshipSet.Relationship.RelationshipKind == RelationshipKind.Association);

            var associationType = (AssociationType)LoadSchemaElement(
                (Som.SchemaType)relationshipSet.Relationship,
                providerManifest,
                convertedItemCache,
                newGlobalItems);

            var associationSet = new AssociationSet(relationshipSet.Name, associationType);

            foreach (var end in relationshipSet.Ends)
            {
                //-- need the EntityType for the end
                var endEntityType = (EntityType)LoadSchemaElement(
                    end.EntitySet.EntityType,
                    providerManifest,
                    convertedItemCache,
                    newGlobalItems);
                //-- need to get the end member
                var endMember = (AssociationEndMember)associationType.Members[end.Name];
                //-- create the end
                var associationSetEnd = new AssociationSetEnd(
                    GetEntitySet(end.EntitySet, container),
                    associationSet,
                    endMember);

                AddOtherContent(end, associationSetEnd);
                associationSet.AddAssociationSetEnd(associationSetEnd);

                // Extract optional Documentation from the end element
                if (end.Documentation != null)
                {
                    associationSetEnd.Documentation = ConvertToDocumentation(end.Documentation);
                }
            }

            // Extract the optional Documentation
            if (relationshipSet.Documentation != null)
            {
                associationSet.Documentation = ConvertToDocumentation(relationshipSet.Documentation);
            }
            AddOtherContent(relationshipSet, associationSet);

            return associationSet;
        }
コード例 #6
0
        /// <summary>
        /// Converts an complex type from SOM to metadata
        /// </summary>
        /// <param name="element">The SOM element to process</param>
        /// <param name="providerManifest">The provider manifest to be used for conversion</param>
        /// <param name="convertedItemCache">The item collection for currently existing metadata objects</param>
        /// <param name="newGlobalItems">The new GlobalItem objects that are created as a result of this conversion</param>
        /// <returns>The complex type object resulting from the convert</returns>
        private static ComplexType ConvertToComplexType(
            Som.SchemaComplexType element,
            DbProviderManifest providerManifest,
            ConversionCache convertedItemCache,
            Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems)
        {
            var complexType = new ComplexType(
                element.Name,
                element.Namespace,
                GetDataSpace(providerManifest));
            newGlobalItems.Add(element, complexType);

            foreach (var somProperty in element.Properties)
            {
                complexType.AddMember(
                    ConvertToProperty(
                        somProperty,
                        providerManifest,
                        convertedItemCache,
                        newGlobalItems));
            }

            // set the abstract and sealed type values for the entity type
            complexType.Abstract = element.IsAbstract;

            if (element.BaseType != null)
            {
                complexType.BaseType = (EdmType)(LoadSchemaElement(
                    element.BaseType,
                    providerManifest,
                    convertedItemCache,
                    newGlobalItems));
            }

            // Extract the optional Documentation
            if (element.Documentation != null)
            {
                complexType.Documentation = ConvertToDocumentation(element.Documentation);
            }
            AddOtherContent(element, complexType);

            return complexType;
        }
コード例 #7
0
        private static AssociationType ConvertToAssociationType(
            Som.Relationship element,
            DbProviderManifest providerManifest,
            ConversionCache convertedItemCache,
            Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems)
        {
            Debug.Assert(element.RelationshipKind == RelationshipKind.Association);

            var associationType = new AssociationType(
                element.Name,
                element.Namespace,
                element.IsForeignKey,
                GetDataSpace(providerManifest));
            newGlobalItems.Add(element, associationType);

            foreach (Som.RelationshipEnd end in element.Ends)
            {
                Som.SchemaType entityTypeElement = end.Type;
                var endEntityType = (EntityType)LoadSchemaElement(
                    entityTypeElement,
                    providerManifest,
                    convertedItemCache,
                    newGlobalItems);

                var endMember = InitializeAssociationEndMember(associationType, end, endEntityType);
                AddOtherContent(end, endMember);
                // Loop through and convert the operations
                foreach (var operation in end.Operations)
                {
                    // Process only the ones that we recognize
                    if (operation.Operation
                        != Som.Operation.Delete)
                    {
                        continue;
                    }

                    // Determine the action for this operation
                    var action = OperationAction.None;
                    switch (operation.Action)
                    {
                        case Som.Action.Cascade:
                            action = OperationAction.Cascade;
                            break;
                        case Som.Action.None:
                            action = OperationAction.None;
                            break;
                        default:
                            Debug.Fail("Operation action not supported.");
                            break;
                    }
                    endMember.DeleteBehavior = action;
                }

                // Extract optional Documentation from the end element
                if (end.Documentation != null)
                {
                    endMember.Documentation = ConvertToDocumentation(end.Documentation);
                }
            }

            Debug.Assert(associationType.ReferentialConstraints.Count == 0, "This must never have been initialized");

            for (var i = 0; i < element.Constraints.Count; i++)
            {
                var constraint = element.Constraints[i];
                var fromMember = (AssociationEndMember)associationType.Members[constraint.PrincipalRole.Name];
                var toMember = (AssociationEndMember)associationType.Members[constraint.DependentRole.Name];
                var fromEntityType = ((RefType)fromMember.TypeUsage.EdmType).ElementType;
                var toEntityType = ((RefType)toMember.TypeUsage.EdmType).ElementType;

                var referentialConstraint = new ReferentialConstraint(
                    fromMember, toMember,
                    GetProperties(fromEntityType, constraint.PrincipalRole.RoleProperties),
                    GetProperties(toEntityType, constraint.DependentRole.RoleProperties));

                // Attach the optional Documentation
                if (constraint.Documentation != null)
                {
                    referentialConstraint.Documentation = ConvertToDocumentation(constraint.Documentation);
                }
                if (constraint.PrincipalRole.Documentation != null)
                {
                    referentialConstraint.FromRole.Documentation = ConvertToDocumentation(constraint.PrincipalRole.Documentation);
                }
                if (constraint.DependentRole.Documentation != null)
                {
                    referentialConstraint.ToRole.Documentation = ConvertToDocumentation(constraint.DependentRole.Documentation);
                }

                associationType.AddReferentialConstraint(referentialConstraint);
                AddOtherContent(element.Constraints[i], referentialConstraint);
            }

            // Extract the optional Documentation
            if (element.Documentation != null)
            {
                associationType.Documentation = ConvertToDocumentation(element.Documentation);
            }
            AddOtherContent(element, associationType);

            return associationType;
        }
コード例 #8
0
        /// <summary>
        /// Converts an entity type from SOM to metadata
        /// 
        /// This method should only build the internally contained and vertical part of the EntityType (keys, properties, and base types) but not 
        /// sideways parts (NavigationProperties) that go between types or we risk trying to access and EntityTypes keys, from the referential constraint,
        /// before the base type, which has the keys, is setup yet.
        /// </summary>
        /// <param name="element">The SOM element to process</param>
        /// <param name="providerManifest">The provider manifest to be used for conversion</param>
        /// <param name="convertedItemCache">The item collection for currently existing metadata objects</param>
        /// <param name="newGlobalItems">The new GlobalItem objects that are created as a result of this conversion</param>
        /// <returns>The entity type object resulting from the convert</returns>
        private static EntityType ConvertToEntityType(
            Som.SchemaEntityType element,
            DbProviderManifest providerManifest,
            ConversionCache convertedItemCache,
            Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems)
        {
            string[] keyMembers = null;
            // Check if this type has keys
            if (element.DeclaredKeyProperties.Count != 0)
            {
                keyMembers = new string[element.DeclaredKeyProperties.Count];
                for (var i = 0; i < keyMembers.Length; i++)
                {
                    //Add the name of the key property to the list of
                    //key properties
                    keyMembers[i] = (element.DeclaredKeyProperties[i].Property.Name);
                }
            }

            var properties = new EdmProperty[element.Properties.Count];
            var index = 0;

            foreach (var somProperty in element.Properties)
            {
                properties[index++] = ConvertToProperty(
                    somProperty,
                    providerManifest,
                    convertedItemCache,
                    newGlobalItems);
            }

            var entityType = new EntityType(
                element.Name,
                element.Namespace,
                GetDataSpace(providerManifest),
                keyMembers,
                properties);

            if (element.BaseType != null)
            {
                entityType.BaseType = (EdmType)(LoadSchemaElement(
                    element.BaseType,
                    providerManifest,
                    convertedItemCache,
                    newGlobalItems));
            }

            // set the abstract and sealed type values for the entity type
            entityType.Abstract = element.IsAbstract;
            // Extract the optional Documentation
            if (element.Documentation != null)
            {
                entityType.Documentation = ConvertToDocumentation(element.Documentation);
            }
            AddOtherContent(element, entityType);
            newGlobalItems.Add(element, entityType);
            return entityType;
        }
コード例 #9
0
        private static void LoadEntityTypePhase2(
            Som.SchemaEntityType element,
            DbProviderManifest providerManifest,
            ConversionCache convertedItemCache,
            Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems)
        {
            var entityType = (EntityType)newGlobalItems[element];

            // Since Navigation properties are internal and not part of member collection, we
            // need to initialize the base class first before we start adding the navigation property
            // this will ensure that all the base navigation properties are initialized
            foreach (var somNavigationProperty in element.NavigationProperties)
            {
                entityType.AddMember(
                    ConvertToNavigationProperty(
                        entityType,
                        somNavigationProperty,
                        providerManifest,
                        convertedItemCache,
                        newGlobalItems));
            }
        }
コード例 #10
0
        /// <summary>
        /// Converts an entity container from SOM to metadata
        /// </summary>
        /// <param name="element">The SOM element to process</param>
        /// <param name="providerManifest">The provider manifest to be used for conversion</param>
        /// <param name="convertedItemCache">The item collection for currently existing metadata objects</param>
        /// <param name="newGlobalItems">The new GlobalItem objects that are created as a result of this conversion</param>
        /// <returns>The entity container object resulting from the convert</returns>
        private static EntityContainer ConvertToEntityContainer(
            Som.EntityContainer element,
            DbProviderManifest providerManifest,
            ConversionCache convertedItemCache,
            Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems)
        {
            // Creating a new entity container object and populate with converted entity set objects
            var entityContainer = new EntityContainer(element.Name, GetDataSpace(providerManifest));
            newGlobalItems.Add(element, entityContainer);

            foreach (var entitySet in element.EntitySets)
            {
                entityContainer.AddEntitySetBase(
                    ConvertToEntitySet(
                        entitySet,
                        providerManifest,
                        convertedItemCache,
                        newGlobalItems));
            }

            // Populate with converted relationship set objects
            foreach (var relationshipSet in element.RelationshipSets)
            {
                Debug.Assert(
                    relationshipSet.Relationship.RelationshipKind == RelationshipKind.Association,
                    "We do not support containment set");

                entityContainer.AddEntitySetBase(
                    ConvertToAssociationSet(
                        relationshipSet,
                        providerManifest,
                        convertedItemCache,
                        entityContainer,
                        newGlobalItems));
            }

            // Populate with converted function imports
            foreach (var functionImport in element.FunctionImports)
            {
                entityContainer.AddFunctionImport(
                    ConvertToFunction(
                        functionImport,
                        providerManifest, convertedItemCache, entityContainer, newGlobalItems));
            }

            // Extract the optional Documentation
            if (element.Documentation != null)
            {
                entityContainer.Documentation = ConvertToDocumentation(element.Documentation);
            }

            AddOtherContent(element, entityContainer);

            return entityContainer;
        }
コード例 #11
0
        internal static MetadataItem LoadSchemaElement(
            Som.SchemaType element,
            DbProviderManifest providerManifest,
            ConversionCache convertedItemCache,
            Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems)
        {
            Debug.Assert(providerManifest != null, "This will make the dataspace to be default SSpace");
            // Try to fetch from the collection first
            GlobalItem item;

            Debug.Assert(
                !convertedItemCache.ItemCollection.TryGetValue(element.FQName, false, out item),
                "Som should have checked for duplicate items");

            // Try to fetch in our collection of new GlobalItems
            if (newGlobalItems.TryGetValue(element, out item))
            {
                return item;
            }

            var entityContainer = element as Som.EntityContainer;
            // Perform different conversion depending on the type of the SOM object
            if (entityContainer != null)
            {
                item = ConvertToEntityContainer(
                    entityContainer,
                    providerManifest,
                    convertedItemCache,
                    newGlobalItems);
            }
            else if (element is Som.SchemaEntityType)
            {
                item = ConvertToEntityType(
                    (Som.SchemaEntityType)element,
                    providerManifest,
                    convertedItemCache,
                    newGlobalItems);
            }
            else if (element is Som.Relationship)
            {
                item = ConvertToAssociationType(
                    (Som.Relationship)element,
                    providerManifest,
                    convertedItemCache,
                    newGlobalItems);
            }
            else if (element is Som.SchemaComplexType)
            {
                item = ConvertToComplexType(
                    (Som.SchemaComplexType)element,
                    providerManifest,
                    convertedItemCache,
                    newGlobalItems);
            }
            else if (element is Som.Function)
            {
                item = ConvertToFunction(
                    (Som.Function)element, providerManifest,
                    convertedItemCache, null, newGlobalItems);
            }
            else if (element is Som.SchemaEnumType)
            {
                item = ConvertToEnumType((Som.SchemaEnumType)element, newGlobalItems);
            }
            else
            {
                // the only type we don't handle is the ProviderManifest TypeElement
                // if it is anything else, it is probably a mistake
                Debug.Assert(
                    element is Som.TypeElement &&
                    element.Schema.DataModel == Som.SchemaDataModelOption.ProviderManifestModel,
                    "Unknown Type in somschema");
                return null;
            }

            return item;
        }
コード例 #12
0
        private static void ConvertSchema(
            Som.Schema somSchema, DbProviderManifest providerManifest,
            ConversionCache convertedItemCache, Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems)
        {
            var funcsWithUnresolvedTypes = new List<Som.Function>();
            foreach (var element in somSchema.SchemaTypes)
            {
                if (null == LoadSchemaElement(element, providerManifest, convertedItemCache, newGlobalItems))
                {
                    var function = element as Som.Function;
                    if (function != null)
                    {
                        funcsWithUnresolvedTypes.Add(function);
                    }
                }
            }

            foreach (var element in somSchema.SchemaTypes.OfType<Som.SchemaEntityType>())
            {
                LoadEntityTypePhase2(element, providerManifest, convertedItemCache, newGlobalItems);
            }

            foreach (var function in funcsWithUnresolvedTypes)
            {
                if (null == LoadSchemaElement(function, providerManifest, convertedItemCache, newGlobalItems))
                {
                    Debug.Fail("Could not load model function definition"); //this should never happen.
                }
            }

            if (convertedItemCache.ItemCollection.DataSpace
                == DataSpace.CSpace)
            {
                var edmCollection = (EdmItemCollection)convertedItemCache.ItemCollection;
                edmCollection.EdmVersion = somSchema.SchemaVersion;
            }
            else
            {
                Debug.Assert(convertedItemCache.ItemCollection.DataSpace == DataSpace.SSpace, "Did you add a new space?");
                // when converting the ProviderManifest, the DataSpace is SSpace, but the ItemCollection is EmptyItemCollection, 
                // not StoreItemCollection
                var storeCollection = convertedItemCache.ItemCollection as StoreItemCollection;
                if (storeCollection != null)
                {
                    storeCollection.StoreSchemaVersion = somSchema.SchemaVersion;
                }
            }
        }
コード例 #13
0
        private static TypeUsage GetFunctionTypeUsage(
            bool isModelFunction,
            Som.Function somFunction,
            Som.FacetEnabledSchemaElement somParameter,
            DbProviderManifest providerManifest,
            bool areConvertingForProviderManifest,
            Som.SchemaType type,
            CollectionKind collectionKind,
            bool isRefType,
            ConversionCache convertedItemCache,
            Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems)
        {
            if (null != somParameter && areConvertingForProviderManifest
                && somParameter.HasUserDefinedFacets)
            {
                return somParameter.TypeUsage;
            }

            if (null == type)
            {
                if (isModelFunction && somParameter != null
                    && somParameter is Som.Parameter)
                {
                    ((Som.Parameter)somParameter).ResolveNestedTypeNames(convertedItemCache, newGlobalItems);
                    return somParameter.TypeUsage;
                }
                else if (somParameter != null
                         && somParameter is Som.ReturnType)
                {
                    ((Som.ReturnType)somParameter).ResolveNestedTypeNames(convertedItemCache, newGlobalItems);
                    return somParameter.TypeUsage;
                }
                else
                {
                    return null;
                }
            }

            EdmType edmType;
            if (!areConvertingForProviderManifest)
            {
                // SOM verifies the type is either scalar, row, or entity
                var scalarType = type as Som.ScalarType;
                if (null != scalarType)
                {
                    if (isModelFunction && somParameter != null)
                    {
                        if (somParameter.TypeUsage == null)
                        {
                            somParameter.ValidateAndSetTypeUsage(scalarType);
                        }
                        return somParameter.TypeUsage;
                    }
                    else if (isModelFunction)
                    {
                        var modelFunction = somFunction as Som.ModelFunction;
                        if (modelFunction.TypeUsage == null)
                        {
                            modelFunction.ValidateAndSetTypeUsage(scalarType);
                        }
                        return modelFunction.TypeUsage;
                    }
                    else if (somParameter != null && somParameter.HasUserDefinedFacets
                             && somFunction.Schema.DataModel == Som.SchemaDataModelOption.ProviderDataModel)
                    {
                        somParameter.ValidateAndSetTypeUsage(scalarType);
                        return somParameter.TypeUsage;
                    }
                    else
                    {
                        edmType = GetPrimitiveType(scalarType, providerManifest);
                    }
                }
                else
                {
                    edmType = (EdmType)LoadSchemaElement(
                        type,
                        providerManifest,
                        convertedItemCache,
                        newGlobalItems);

                    // Neither FunctionImport nor its Parameters can have facets when defined in CSDL so for enums, 
                    // since they are only a CSpace concept, we need to process facets only on model functions 
                    if (isModelFunction && type is Som.SchemaEnumType)
                    {
                        Debug.Assert(somFunction.Schema.DataModel == Som.SchemaDataModelOption.EntityDataModel, "Enums live only in CSpace");

                        if (somParameter != null)
                        {
                            somParameter.ValidateAndSetTypeUsage(edmType);
                            return somParameter.TypeUsage;
                        }
                        else if (somFunction != null)
                        {
                            var modelFunction = ((Som.ModelFunction)somFunction);
                            modelFunction.ValidateAndSetTypeUsage(edmType);
                            return modelFunction.TypeUsage;
                        }
                        else
                        {
                            Debug.Fail("Should never get here.");
                        }
                    }
                }
            }
            else if (type is Som.TypeElement)
            {
                var typeElement = type as Som.TypeElement;
                edmType = typeElement.PrimitiveType;
            }
            else
            {
                var typeElement = type as Som.ScalarType;
                edmType = typeElement.Type;
            }

            //Construct type usage
            TypeUsage usage;
            if (collectionKind != CollectionKind.None)
            {
                usage = convertedItemCache.GetCollectionTypeUsageWithNullFacets(edmType);
            }
            else
            {
                var entityType = edmType as EntityType;
                if (entityType != null && isRefType)
                {
                    usage = TypeUsage.Create(new RefType(entityType));
                }
                else
                {
                    usage = convertedItemCache.GetTypeUsageWithNullFacets(edmType);
                }
            }

            return usage;
        }
コード例 #14
0
        internal static IEnumerable<GlobalItem> ConvertSchema(
            IList<Som.Schema> somSchemas,
            DbProviderManifest providerManifest,
            ItemCollection itemCollection)
        {
            var newGlobalItems = new Dictionary<Som.SchemaElement, GlobalItem>();
            var conversionCache = new ConversionCache(itemCollection);

            foreach (var somSchema in somSchemas)
            {
                ConvertSchema(somSchema, providerManifest, conversionCache, newGlobalItems);
            }

            return newGlobalItems.Values;
        }