/// <summary> /// Determines the store type for a function import. /// </summary> private TypeUsage DetermineStoreResultType( FunctionImportMappingNonComposable mapping, int resultSetIndex, out IColumnMapGenerator columnMapGenerator) { // Determine column maps and infer result types for the mapped function. There are four varieties: // Collection(Entity) // Collection(PrimitiveType) // Collection(ComplexType) // No result type TypeUsage storeResultType; { StructuralType baseStructuralType; var functionImport = mapping.FunctionImport; // Collection(Entity) or Collection(ComplexType) if (MetadataHelper.TryGetFunctionImportReturnType(functionImport, resultSetIndex, out baseStructuralType)) { ValidateEdmResultType(baseStructuralType, functionImport); //Note: Defensive check for historic reasons, we expect functionImport.EntitySets.Count > resultSetIndex var entitySet = functionImport.EntitySets.Count > resultSetIndex ? functionImport.EntitySets[resultSetIndex] : null; columnMapGenerator = new FunctionColumnMapGenerator( mapping, resultSetIndex, entitySet, baseStructuralType, _columnMapFactory); // We don't actually know the return type for the stored procedure, but we can infer // one based on the mapping (i.e.: a column for every property of the mapped types // and for all discriminator columns) storeResultType = mapping.GetExpectedTargetResultType(resultSetIndex); } // Collection(PrimitiveType) else { var returnParameter = MetadataHelper.GetReturnParameter(functionImport, resultSetIndex); if (returnParameter != null && returnParameter.TypeUsage != null) { // Get metadata description of the return type storeResultType = returnParameter.TypeUsage; Debug.Assert( storeResultType.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType, "FunctionImport currently supports only collection result type"); var elementType = ((CollectionType)storeResultType.EdmType).TypeUsage; Debug.Assert( Helper.IsScalarType(elementType.EdmType), "FunctionImport supports only Collection(Entity), Collection(Enum) and Collection(Primitive)"); // Build collection column map where the first column of the store result is assumed // to contain the primitive type values. var scalarColumnMap = new ScalarColumnMap(elementType, string.Empty, 0, 0); var collectionColumnMap = new SimpleCollectionColumnMap( storeResultType, string.Empty, scalarColumnMap, null, null); columnMapGenerator = new ConstantColumnMapGenerator(collectionColumnMap, 1); } // No result type else { storeResultType = null; columnMapGenerator = new ConstantColumnMapGenerator(null, 0); } } } return(storeResultType); }
/// <summary> /// Determines the store type for a function import. /// </summary> private TypeUsage DetermineStoreResultType(MetadataWorkspace workspace, FunctionImportMappingNonComposable mapping, int resultSetIndex, out IColumnMapGenerator columnMapGenerator) { // Determine column maps and infer result types for the mapped function. There are four varieties: // Collection(Entity) // Collection(PrimitiveType) // Collection(ComplexType) // No result type TypeUsage storeResultType; { StructuralType baseStructuralType; EdmFunction functionImport = mapping.FunctionImport; // Collection(Entity) or Collection(ComplexType) if (MetadataHelper.TryGetFunctionImportReturnType<StructuralType>(functionImport, resultSetIndex, out baseStructuralType)) { ValidateEdmResultType(baseStructuralType, functionImport); //Note: Defensive check for historic reasons, we expect functionImport.EntitySets.Count > resultSetIndex EntitySet entitySet = functionImport.EntitySets.Count > resultSetIndex ? functionImport.EntitySets[resultSetIndex] : null; columnMapGenerator = new FunctionColumnMapGenerator(mapping, resultSetIndex, entitySet, baseStructuralType); // We don't actually know the return type for the stored procedure, but we can infer // one based on the mapping (i.e.: a column for every property of the mapped types // and for all discriminator columns) storeResultType = mapping.GetExpectedTargetResultType(workspace, resultSetIndex); } // Collection(PrimitiveType) else { FunctionParameter returnParameter = MetadataHelper.GetReturnParameter(functionImport, resultSetIndex); if (returnParameter != null && returnParameter.TypeUsage != null) { // Get metadata description of the return type storeResultType = returnParameter.TypeUsage; Debug.Assert(storeResultType.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType, "FunctionImport currently supports only collection result type"); TypeUsage elementType = ((CollectionType)storeResultType.EdmType).TypeUsage; Debug.Assert(Helper.IsScalarType(elementType.EdmType) , "FunctionImport supports only Collection(Entity), Collection(Enum) and Collection(Primitive)"); // Build collection column map where the first column of the store result is assumed // to contain the primitive type values. ScalarColumnMap scalarColumnMap = new ScalarColumnMap(elementType, string.Empty, 0, 0); SimpleCollectionColumnMap collectionColumnMap = new SimpleCollectionColumnMap(storeResultType, string.Empty, scalarColumnMap, null, null); columnMapGenerator = new ConstantColumnMapGenerator(collectionColumnMap, 1); } // No result type else { storeResultType = null; columnMapGenerator = new ConstantColumnMapGenerator(null, 0); } } } return storeResultType; }