internal StorageModificationFunctionMapping(
            EntitySetBase entitySet,
            EntityTypeBase entityType,
            EdmFunction function,
            IEnumerable<StorageModificationFunctionParameterBinding> parameterBindings,
            FunctionParameter rowsAffectedParameter,
            IEnumerable<StorageModificationFunctionResultBinding> resultBindings)
        {
            //Contract.Requires(entitySet != null);
            //Contract.Requires(function != null);
            //Contract.Requires(parameterBindings != null);

            Function = function;
            RowsAffectedParameter = rowsAffectedParameter;
            ParameterBindings = parameterBindings.ToList().AsReadOnly();
            if (null != resultBindings)
            {
                var bindings = resultBindings.ToList();
                if (0 < bindings.Count)
                {
                    ResultBindings = bindings.AsReadOnly();
                }
            }
            CollocatedAssociationSetEnds =
                GetReferencedAssociationSetEnds(entitySet as EntitySet, entityType as EntityType, parameterBindings)
                    .ToList()
                    .AsReadOnly();
        }
        internal StorageModificationFunctionParameterBinding(
            FunctionParameter parameter, StorageModificationFunctionMemberPath memberPath, bool isCurrent)
        {
            //Contract.Requires(parameter != null);
            //Contract.Requires(memberPath != null);

            Parameter = parameter;
            MemberPath = memberPath;
            IsCurrent = isCurrent;
        }
        private void AddFunction(PrimitiveTypeKind returnType, string functionName, KeyValuePair <string, PrimitiveTypeKind>[] parameterDefinitions)
        {
            FunctionParameter returnParameter = CreateReturnParameter(returnType);

            FunctionParameter[] parameters = parameterDefinitions.Select(paramDef => CreateParameter(paramDef.Value, paramDef.Key)).ToArray();

            EdmFunction function = new EdmFunction(functionName,
                                                   EdmConstants.EdmNamespace,
                                                   DataSpace.CSpace,
                                                   new EdmFunctionPayload
            {
                IsBuiltIn              = true,
                ReturnParameters       = new FunctionParameter[] { returnParameter },
                Parameters             = parameters,
                IsFromProviderManifest = true,
            });

            function.SetReadOnly();

            this.functions.Add(function);
        }
        /// <summary>
        /// Converts a function from SOM to metadata
        /// </summary>
        /// <param name="somFunction">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="functionImportEntityContainer">For function imports, the entity container including the function declaration</param>
        /// <param name="newGlobalItems">The new GlobalItem objects that are created as a result of this conversion</param>
        /// <returns>The function object resulting from the convert</returns>
        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;
            }

            bool areConvertingForProviderManifest = somFunction.Schema.DataModel == Som.SchemaDataModelOption.ProviderManifestModel;
            List<FunctionParameter> returnParameters = new List<FunctionParameter>();
            if (somFunction.ReturnTypeList != null)
            {
                int i = 0;
                foreach (Som.ReturnType somReturnType in somFunction.ReturnTypeList)
                {
                    TypeUsage returnType = GetFunctionTypeUsage(somFunction is Som.ModelFunction,
                                                            somFunction,
                                                            somReturnType,
                                                            providerManifest,
                                                            areConvertingForProviderManifest,
                                                            somReturnType.Type,
                                                            somReturnType.CollectionKind,
                                                            somReturnType.IsRefType /*isRefType*/,
                                                            somFunction,
                                                            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
                        string modifier = i == 0 ? string.Empty : i.ToString(System.Globalization.CultureInfo.InvariantCulture);
                        i++;
                        FunctionParameter 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)
            {
                TypeUsage returnType = GetFunctionTypeUsage(somFunction is Som.ModelFunction,
                                                        somFunction,
                                                        null,
                                                        providerManifest,
                                                        areConvertingForProviderManifest,
                                                        somFunction.Type,
                                                        somFunction.CollectionKind,
                                                        somFunction.IsReturnAttributeReftype /*isRefType*/,
                                                        somFunction,
                                                        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 EntitySet[] { GetEntitySet(somFunctionImport.EntitySet, entityContainer) };
                }
                else if (null != somFunctionImport.ReturnTypeList)
                {
                    Debug.Assert(functionImportEntityContainer != null, "functionImportEntityContainer must be specified during function import conversion");
                    EntityContainer entityContainer = functionImportEntityContainer;
                    entitySets = somFunctionImport.ReturnTypeList
                        .Select(returnType => null != returnType.EntitySet
                            ? GetEntitySet(returnType.EntitySet, functionImportEntityContainer)
                            : null)
                        .ToArray();
                }
            }
            else
            {
                functionNamespace = somFunction.Namespace;
            }

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

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

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

            EdmFunction 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;
        }
Example #5
0
        /// <summary>
        /// Convert the S type function parameters and returnType to C types.
        /// </summary>
        private EdmFunction ConvertFunctionSignatureToCType(EdmFunction sTypeFunction)
        {
            Debug.Assert(sTypeFunction.DataSpace == Edm.DataSpace.SSpace, "sTypeFunction.DataSpace == Edm.DataSpace.SSpace");

            if (sTypeFunction.IsFromProviderManifest)
            {
                return(sTypeFunction);
            }

            FunctionParameter returnParameter = null;

            if (sTypeFunction.ReturnParameter != null)
            {
                TypeUsage edmTypeUsageReturnParameter =
                    MetadataHelper.ConvertStoreTypeUsageToEdmTypeUsage(sTypeFunction.ReturnParameter.TypeUsage);

                returnParameter =
                    new FunctionParameter(
                        sTypeFunction.ReturnParameter.Name,
                        edmTypeUsageReturnParameter,
                        sTypeFunction.ReturnParameter.GetParameterMode());
            }

            List <FunctionParameter> parameters = new List <FunctionParameter>();

            if (sTypeFunction.Parameters.Count > 0)
            {
                foreach (var parameter in sTypeFunction.Parameters)
                {
                    TypeUsage edmTypeUsage = MetadataHelper.ConvertStoreTypeUsageToEdmTypeUsage(parameter.TypeUsage);

                    FunctionParameter edmTypeParameter = new FunctionParameter(parameter.Name, edmTypeUsage, parameter.GetParameterMode());
                    parameters.Add(edmTypeParameter);
                }
            }

            FunctionParameter[] returnParameters =
                returnParameter == null ? new FunctionParameter[0] : new FunctionParameter[] { returnParameter };
            EdmFunction edmFunction = new EdmFunction(sTypeFunction.Name,
                                                      sTypeFunction.NamespaceName,
                                                      DataSpace.CSpace,
                                                      new EdmFunctionPayload
            {
                Schema                 = sTypeFunction.Schema,
                StoreFunctionName      = sTypeFunction.StoreFunctionNameAttribute,
                CommandText            = sTypeFunction.CommandTextAttribute,
                IsAggregate            = sTypeFunction.AggregateAttribute,
                IsBuiltIn              = sTypeFunction.BuiltInAttribute,
                IsNiladic              = sTypeFunction.NiladicFunctionAttribute,
                IsComposable           = sTypeFunction.IsComposableAttribute,
                IsFromProviderManifest = sTypeFunction.IsFromProviderManifest,
                IsCachedStoreFunction  = true,
                IsFunctionImport       = sTypeFunction.IsFunctionImport,
                ReturnParameters       = returnParameters,
                Parameters             = parameters.ToArray(),
                ParameterTypeSemantics = sTypeFunction.ParameterTypeSemanticsAttribute,
            });

            edmFunction.SetReadOnly();

            return(edmFunction);
        }
        protected override void Visit(FunctionParameter functionParameter)
        {
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(functionParameter, out index))
            {
                return;
            }

            this.AddObjectStartDumpToHashBuilder(functionParameter, index);

            #region Inner data visit
            this.AddObjectContentToHashBuilder(functionParameter.Identity);
            // Identity already has Name
            this.AddObjectContentToHashBuilder(functionParameter.Mode);

            base.Visit(functionParameter);

            #endregion

            this.AddObjectEndDumpToHashBuilder();
        }
 private string FunctionImportTypeName(FunctionParameter parameter)
 {
     return parameter.Mode == ParameterMode.In ? parameter.TypeUsage.EdmType.Name : "ObjectParameter";
 }
        private void CreateEdmFunction(LoadMethodSessionState session, DbObjectKey functionKey, List<FunctionDetailsReader.Memento> parameters)
        {
            Debug.Assert(parameters.Count != 0, "don't call the method with no data");

            FunctionDetailsReader row = parameters[0].CreateReader();

            FunctionParameter returnParameter = null;
            bool isValid = true;
            List<EdmSchemaError> errors = new List<EdmSchemaError>();
            if (row.ReturnType != null)
            {
                Debug.Assert(!row.IsTvf, "TVF can't have ReturnType (used only for scalars).");
                bool excludedForTarget;
                TypeUsage returnType = GetScalarFunctionTypeUsage(session, row.ReturnType, out excludedForTarget);
                if (returnType != null)
                {
                    returnParameter = new FunctionParameter(EdmConstants.ReturnType, returnType, ParameterMode.ReturnValue);
                }
                else
                {
                    isValid = false;
                    errors.Add(new EdmSchemaError(excludedForTarget ?
                                                  Strings.UnsupportedFunctionReturnDataTypeForTarget(row.ProcedureName, row.ReturnType) :
                                                  Strings.UnsupportedFunctionReturnDataType(row.ProcedureName, row.ReturnType),
                                                  (int)ModelBuilderErrorCode.UnsupportedType,
                                                  EdmSchemaErrorSeverity.Warning));
                }
            }
            else if (row.IsTvf)
            {
                if (_targetEntityFrameworkVersion < EntityFrameworkVersions.Version3)
                {
                    return;
                }
                RowType tvfReturnType;
                if (session.TryGetTvfReturnType(functionKey, out tvfReturnType) && !session.InvalidTypes.Contains(tvfReturnType))
                {
                    var collectionType = tvfReturnType.GetCollectionType();
                    collectionType.SetReadOnly();
                    returnParameter = new FunctionParameter(EdmConstants.ReturnType, TypeUsage.Create(collectionType), ParameterMode.ReturnValue);
                }
                else
                {
                    isValid = false;

                    // If the TVF return type exists, but it is not valid, then reassign all its errors directly to the TVF.
                    // This is needed in order to avoid the following kind of error reporting:
                    // SSDL:
                    // 
                    // <!-- Errors found while generating type:
                    //    column1 type not supported
                    //    column2 type not supported
                    //   <RowType />
                    // -->
                    // ...
                    // ...
                    // <!-- Error found while generating type:
                    //    TableReferencedByTvfWasNotFound
                    //   <Function Name="TVF" .... />
                    // -->
                    // 
                    // Instead we want something like this:
                    // 
                    // <!-- Errors found while generating type:
                    //    column1 type not supported
                    //    column2 type not supported
                    //    TableReferencedByTvfWasNotFound
                    //   <Function Name="TVF" .... />
                    // -->
                    // 

                    List<EdmSchemaError> tvfReturnTypeErrors;
                    if (tvfReturnType != null && session.ItemToErrorsMap.TryGetValue(tvfReturnType, out tvfReturnTypeErrors))
                    {
                        errors.AddRange(tvfReturnTypeErrors);
                        session.ItemToErrorsMap.Remove(tvfReturnType);
                        if (session.InvalidTypes.Contains(tvfReturnType))
                        {
                            session.InvalidTypes.Remove(tvfReturnType);
                        }
                    }
                    
                    errors.Add(new EdmSchemaError(
                        Strings.TableReferencedByTvfWasNotFound(functionKey),
                        (int)ModelBuilderErrorCode.MissingTvfReturnTable,
                        EdmSchemaErrorSeverity.Warning));
                }
            }
            
            bool caseSensitive = false;
            UniqueIdentifierService uniqueIdentifiers = new UniqueIdentifierService(caseSensitive);
            List<FunctionParameter> functionParameters = new List<FunctionParameter>();
            for (int i = 0; i < parameters.Count && !row.IsParameterNameNull; i++)
            {
                row.Attach(parameters[i]);
                TypeUsage parameterType = null;
                bool excludedForTarget = false;
                if (!row.IsParameterTypeNull)
                {
                    parameterType = GetScalarFunctionTypeUsage(session, row.ParameterType, out excludedForTarget);
                }

                if (parameterType != null)
                {
                    ParameterMode mode;
                    if (!row.TryGetParameterMode(out mode))
                    {
                        isValid = false;
                        string modeValue = "null";
                        if (!row.IsParameterModeNull)
                        {
                            modeValue = row.ProcParameterMode;
                        }
                        errors.Add(new EdmSchemaError(
                            Strings.ParameterDirectionNotValid(
                            row.ProcedureName,
                            row.ParameterName,
                            modeValue),
                            (int)ModelBuilderErrorCode.ParameterDirectionNotValid,
                            EdmSchemaErrorSeverity.Warning));
                    }

                    // the mode will get defaulted to something, so it is ok to keep creating after
                    // an error getting the mode value.
                    string parameterName = EntityModelSchemaGenerator.CreateValidEcmaName(row.ParameterName, 'p');
                    parameterName = uniqueIdentifiers.AdjustIdentifier(parameterName);
                    FunctionParameter parameter = new FunctionParameter(parameterName, parameterType, mode);
                    functionParameters.Add(parameter);
                }
                else
                {
                    isValid = false;
                    string typeValue = "null";
                    if (!row.IsParameterTypeNull)
                    {
                        typeValue = row.ParameterType;
                    }
                    errors.Add(new EdmSchemaError(excludedForTarget ?
                                                  Strings.UnsupportedFunctionParameterDataTypeForTarget(row.ProcedureName, row.ParameterName, i, typeValue) :
                                                  Strings.UnsupportedFunctionParameterDataType(row.ProcedureName, row.ParameterName, i, typeValue),
                                                  (int)ModelBuilderErrorCode.UnsupportedType,
                                                  EdmSchemaErrorSeverity.Warning));
                }
            }

            string functionName = EntityModelSchemaGenerator.CreateValidEcmaName(row.ProcedureName, 'f');
            functionName = session.UsedTypeNames.AdjustIdentifier(functionName);
            FunctionParameter[] returnParameters = 
                returnParameter == null ? new FunctionParameter[0] : new FunctionParameter[] {returnParameter};
            EdmFunction function = new EdmFunction(functionName,
                _namespaceName,
                DataSpace.SSpace,
                new EdmFunctionPayload
                {
                    Schema = row.Schema,
                    StoreFunctionName = functionName != row.ProcedureName ? row.ProcedureName : null,
                    IsAggregate = row.IsIsAggregate,
                    IsBuiltIn = row.IsBuiltIn,
                    IsNiladic = row.IsNiladic,
                    IsComposable = row.IsComposable,
                    ReturnParameters = returnParameters,
                    Parameters = functionParameters.ToArray()
                });
            function.SetReadOnly();

            session.AddErrorsForType(function, errors);
            if (isValid)
            {
                session.Functions.Add(function);
            }
            else
            {
                session.InvalidTypes.Add(function);
            }
        }
 protected virtual void Visit(FunctionParameter functionParameter)
 {
     Visit(functionParameter.DeclaringFunction);
     Visit(functionParameter.TypeUsage);
 }
 internal StorageModificationFunctionParameterBinding(FunctionParameter parameter, StorageModificationFunctionMemberPath memberPath, bool isCurrent)
 {
     this.Parameter = EntityUtil.CheckArgumentNull(parameter, "parameter");
     this.MemberPath = EntityUtil.CheckArgumentNull(memberPath, "memberPath");
     this.IsCurrent = isCurrent;
 }
 internal StorageModificationFunctionMapping(
     EntitySetBase entitySet,
     EntityTypeBase entityType,
     EdmFunction function,
     IEnumerable<StorageModificationFunctionParameterBinding> parameterBindings,
     FunctionParameter rowsAffectedParameter,
     IEnumerable<StorageModificationFunctionResultBinding> resultBindings)
 {
     EntityUtil.CheckArgumentNull(entitySet, "entitySet");
     this.Function = EntityUtil.CheckArgumentNull(function, "function");
     this.RowsAffectedParameter = rowsAffectedParameter;
     this.ParameterBindings = EntityUtil.CheckArgumentNull(parameterBindings, "parameterBindings")
         .ToList().AsReadOnly();
     if (null != resultBindings)
     {
         List<StorageModificationFunctionResultBinding> bindings = resultBindings.ToList();
         if (0 < bindings.Count)
         {
             ResultBindings = bindings.AsReadOnly();
         }
     }
     this.CollocatedAssociationSetEnds = GetReferencedAssociationSetEnds(entitySet as EntitySet, entityType as EntityType, parameterBindings)
         .ToList()
         .AsReadOnly();
 }
        // requires: parameter type is constrained to be a scalar type
        // Determines CLR type for function parameter
        private static Type DetermineParameterType(FunctionParameter parameter)
        {
            Debug.Assert(null != parameter && MetadataUtil.IsPrimitiveType(parameter.TypeUsage.EdmType),
                "validation must ensure only scalar type parameter are given");

            if (parameter.Mode != ParameterMode.In)
            {
                // non input parameter must be treated as ObjectParameter instances so that the 
                // value can be set asynchronously (after the method has yielded and the reader
                // has been consumed)
                return typeof(ObjectParameter);
            }

            PrimitiveType parameterType = (PrimitiveType)parameter.TypeUsage.EdmType;
            Type clrType = parameterType.ClrType;
            return clrType;
        }
        private void CreateFunctionArgument(CodeMemberMethod method, UniqueIdentifierService uniqueIdentifierService, FunctionParameter parameter)
        {
            // get type of parameter
            Type clrType = DetermineParameterType(parameter);

            // parameters to stored procedures must be nullable
            CodeTypeReference argumentType = clrType.IsValueType ? TypeReference.NullableForType(clrType) : TypeReference.ForType(clrType);
            string parameterName = uniqueIdentifierService.AdjustIdentifier(parameter.Name, parameter);
            CodeParameterDeclarationExpression codeParameter = new CodeParameterDeclarationExpression(argumentType, parameterName);
            method.Parameters.Add(codeParameter);
        }
        private CodeExpression CreateFunctionParameter(CodeMemberMethod method, UniqueIdentifierService uniqueIdentifierService, FunctionParameter parameter)
        {
            // get (adjusted) name of parameter
            string adjustedParameterName;
            if (!uniqueIdentifierService.TryGetAdjustedName(parameter, out adjustedParameterName))
            {
                Debug.Fail("parameter must be registered in identifier service");
            }
            Type parameterType = DetermineParameterType(parameter);

            // make sure the variable name does not collide with any parameters to the method, or any
            // existing variables (all registered in the service)
            string variableName = uniqueIdentifierService.AdjustIdentifier(parameter.Name + "Parameter");

            // ObjectParameter variableName;
            // if (null != parameterName)
            // {
            //     variableName = new ObjectParameter("parameterName", adjustedParameterName);
            // }
            // else
            // {
            //     variableName = new ObjectParameter("parameterName", typeof(parameterType));
            // }
            method.Statements.Add(
                new CodeVariableDeclarationStatement(TypeReference.ForType(typeof(ObjectParameter)), variableName));
            CodeExpression variableReference = new CodeVariableReferenceExpression(variableName);
            CodeExpression parameterReference = new CodeVariableReferenceExpression(adjustedParameterName);
            CodeStatement nullConstructor = new CodeAssignStatement(variableReference,
                new CodeObjectCreateExpression(TypeReference.ForType(typeof(ObjectParameter)),
                new CodePrimitiveExpression(parameter.Name),
                new CodeTypeOfExpression(TypeReference.ForType(parameterType))));
            CodeStatement valueConstructor = new CodeAssignStatement(variableReference,
                new CodeObjectCreateExpression(TypeReference.ForType(typeof(ObjectParameter)),
                new CodePrimitiveExpression(parameter.Name),
                parameterReference));
            CodeExpression notNullCondition;
            if (parameterType.IsValueType)
            {
                // Value type parameters generate Nullable<ValueType> arguments (see CreateFunctionArgument).
                // We call Nullable<ValueType>.HasValue to determine whether the argument passed in is null
                // (since null != nullableTypeInstance does not work in VB)
                //
                // parameterReference.HasValue
                notNullCondition = new CodePropertyReferenceExpression(
                    parameterReference,
                    "HasValue");
            }
            else
            {
                // use parameterReference != null
                notNullCondition = new CodeBinaryOperatorExpression(
                    parameterReference,
                    CodeBinaryOperatorType.IdentityInequality,
                    NullExpression);
            }
            method.Statements.Add(
                new CodeConditionStatement(
                    notNullCondition,
                    new CodeStatement[] { valueConstructor, },
                    new CodeStatement[] { nullConstructor, }
                )
            );
            return variableReference;
        }
 private FunctionParameter CreateFunctionImportParameter(FunctionParameter storeParameter, UniqueIdentifierService usedParameterNames)
 {
     Debug.Assert(storeParameter.Mode == ParameterMode.In, "Function import mapping is supported only for 'In' parameters.");
     string name = CreateModelName(storeParameter.Name, usedParameterNames);
     TypeUsage cspaceTypeUsage = storeParameter.TypeUsage.GetModelTypeUsage();
     var modelParameter = new FunctionParameter(name, cspaceTypeUsage, storeParameter.Mode);
     return modelParameter;
 }
 // Adds and registers a DbParameter taking the number of rows affected
 internal void RegisterRowsAffectedParameter(FunctionParameter rowsAffectedParameter)
 {
     if (null != rowsAffectedParameter)
     {
         Debug.Assert(rowsAffectedParameter.Mode == ParameterMode.Out || rowsAffectedParameter.Mode == ParameterMode.InOut,
             "when loading mapping metadata, we check that the parameter is an out parameter");
         m_rowsAffectedParameter = m_dbCommand.Parameters[rowsAffectedParameter.Name];
     }
 }
        /// <summary>
        /// Convert the S type function parameters and returnType to C types.
        /// </summary>
        private EdmFunction ConvertFunctionSignatureToCType(EdmFunction sTypeFunction)
        {
            Debug.Assert(sTypeFunction.DataSpace == Edm.DataSpace.SSpace, "sTypeFunction.DataSpace == Edm.DataSpace.SSpace");

            if (sTypeFunction.IsFromProviderManifest)
            {
                return sTypeFunction;
            }
            
            FunctionParameter returnParameter = null;
            if (sTypeFunction.ReturnParameter != null)
            {
                TypeUsage edmTypeUsageReturnParameter =
                    MetadataHelper.ConvertStoreTypeUsageToEdmTypeUsage(sTypeFunction.ReturnParameter.TypeUsage);

                returnParameter =
                    new FunctionParameter(
                        sTypeFunction.ReturnParameter.Name,
                        edmTypeUsageReturnParameter,
                        sTypeFunction.ReturnParameter.GetParameterMode());
            }

            List<FunctionParameter> parameters = new List<FunctionParameter>();
            if (sTypeFunction.Parameters.Count > 0)
            {
                
                foreach (var parameter in sTypeFunction.Parameters)
                {
                    TypeUsage edmTypeUsage = MetadataHelper.ConvertStoreTypeUsageToEdmTypeUsage(parameter.TypeUsage);

                    FunctionParameter edmTypeParameter = new FunctionParameter(parameter.Name, edmTypeUsage, parameter.GetParameterMode());
                    parameters.Add(edmTypeParameter);
                }
            }

            FunctionParameter[] returnParameters = 
                returnParameter == null ? new FunctionParameter[0] : new FunctionParameter[] { returnParameter };
            EdmFunction edmFunction = new EdmFunction(sTypeFunction.Name, 
                sTypeFunction.NamespaceName,
                DataSpace.CSpace,
                new EdmFunctionPayload
                {
                    Schema = sTypeFunction.Schema,
                    StoreFunctionName = sTypeFunction.StoreFunctionNameAttribute,
                    CommandText = sTypeFunction.CommandTextAttribute,
                    IsAggregate = sTypeFunction.AggregateAttribute,
                    IsBuiltIn = sTypeFunction.BuiltInAttribute,
                    IsNiladic = sTypeFunction.NiladicFunctionAttribute,
                    IsComposable = sTypeFunction.IsComposableAttribute,
                    IsFromProviderManifest = sTypeFunction.IsFromProviderManifest,
                    IsCachedStoreFunction = true,
                    IsFunctionImport = sTypeFunction.IsFunctionImport,
                    ReturnParameters = returnParameters,
                    Parameters = parameters.ToArray(),
                    ParameterTypeSemantics = sTypeFunction.ParameterTypeSemanticsAttribute,
                });

            edmFunction.SetReadOnly();

            return edmFunction;
        }
 /// <summary>
 /// This method returns the string representation of the given <paramref name="parameter"/>.
 /// </summary>
 /// <param name="parameter">A <see cref="FunctionParameter"/> representing the function perameter.</param>
 /// <returns>The string representation of the given parameter.</returns>
 protected string GetTypeString(FunctionParameter parameter)
 {
     return GetTypeString(parameter.TypeUsage.EdmType, true);
 }