private void MapFunctions(LoadMethodSessionState session, EntityContainer modelEntityContainer)
        {
            if (_storeFunctions == null || _storeFunctions.Length == 0 || _targetEntityFrameworkVersion < EntityFrameworkVersions.Version3)
            {
                return;
            }

            //
            // Create function imports and appropriate complex types for return parameters and add them to the item collection (session.EdmItemCollection).
            // Create and add function mappings.
            //

            var interestingStoreFunctions = _storeFunctions.Where(
                f => f.IsComposableAttribute &&
                     !f.AggregateAttribute &&
                     f.Parameters.All(p => p.Mode == ParameterMode.In));
            foreach (var storeFunction in interestingStoreFunctions)
            {
                RowType tvfReturnType = TypeHelpers.GetTvfReturnType(storeFunction);
                if (tvfReturnType == null)
                {
                    continue;
                }

                // Create function import name.
                string functionImportName = CreateModelName(storeFunction.Name, session.UsedEntityContainerItemNames);
               
                // Create function import parameters.
                UniqueIdentifierService usedParameterNames = new UniqueIdentifierService(false);
                var parameters = storeFunction.Parameters.Select(p => CreateFunctionImportParameter(p, usedParameterNames)).ToArray();
                var failedStoreParameterName = storeFunction.Parameters.Select(p => p.Name).Except(parameters.Select(p => p.Name)).FirstOrDefault();
                if (failedStoreParameterName != null)
                {
                    session.AddError(Strings.UnableToGenerateFunctionImportParameterName(failedStoreParameterName, storeFunction.Identity),
                        ModelBuilderErrorCode.UnableToGenerateFunctionImportParameterName, EdmSchemaErrorSeverity.Warning, null);
                    continue;
                }

                // Create new complex type and register it in the item collection.
                var complexType = CreateModelComplexTypeForTvfResult(session, functionImportName, tvfReturnType);
                complexType.SetReadOnly();
                session.EdmItemCollection.AddInternal(complexType);

                var collectionType = complexType.GetCollectionType();
                collectionType.SetReadOnly();
                var returnTypeUsage = TypeUsage.Create(collectionType);

                // Create function import and register it in the item collection.
                var functionImport = new EdmFunction(functionImportName, _modelEntityContainerName, DataSpace.CSpace, new EdmFunctionPayload()
                {
                    Name = functionImportName,
                    NamespaceName = _namespaceName,
                    ReturnParameters = new FunctionParameter[] {new FunctionParameter(EdmConstants.ReturnType, returnTypeUsage, ParameterMode.ReturnValue)},
                    Parameters = parameters,
                    DataSpace = DataSpace.CSpace,
                    IsComposable = true,
                    IsFunctionImport = true
                });
                functionImport.SetReadOnly();
                modelEntityContainer.AddFunctionImport(functionImport);

                // Add mapping tuple.
                session.MappingLookups.StoreFunctionToFunctionImport.Add(Tuple.Create(storeFunction, functionImport));
            }
        }
예제 #2
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
            EntityContainer entityContainer = new EntityContainer(element.Name, GetDataSpace(providerManifest));
            newGlobalItems.Add(element, entityContainer);

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

            // Populate with converted relationship set objects
            foreach (Som.EntityContainerRelationshipSet 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 (Som.Function 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;
        }