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)); } }
/// <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; }