public override string GenerateSQL(DbCommandTree commandTree)
        {
            DbFunctionCommandTree tree     = (commandTree as DbFunctionCommandTree);
            EdmFunction           function = tree.EdmFunction;

            CommandType = CommandType.StoredProcedure;

            string cmdText = (string)function.MetadataProperties["CommandTextAttribute"].Value;

            if (String.IsNullOrEmpty(cmdText))
            {
                string schema = (string)function.MetadataProperties["Schema"].Value;
                if (String.IsNullOrEmpty(schema))
                {
                    schema = function.NamespaceName;
                }

                string functionName = (string)function.MetadataProperties["StoreFunctionNameAttribute"].Value;
                if (String.IsNullOrEmpty(functionName))
                {
                    functionName = function.Name;
                }

                return(String.Format("`{0}`", functionName));
            }
            else
            {
                CommandType = CommandType.Text;
                return(cmdText);
            }
        }
        /// <summary>
        /// Sets the expected column types for a given function command tree
        /// </summary>
        private void SetFunctionExpectedTypes(DbFunctionCommandTree tree, EFMySqlCommand cmd)
        {
            if (tree.ResultType != null)
            {
                Debug.Assert(tree.ResultType.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType,
                             Resources.WrongFunctionResultType);

                CollectionType collectionType = (CollectionType)(tree.ResultType.EdmType);
                EdmType        elementType    = collectionType.TypeUsage.EdmType;

                if (elementType.BuiltInTypeKind == BuiltInTypeKind.RowType)
                {
                    ReadOnlyMetadataCollection <EdmMember> members = ((RowType)elementType).Members;
                    cmd.ColumnTypes = new PrimitiveType[members.Count];

                    for (int ordinal = 0; ordinal < members.Count; ordinal++)
                    {
                        EdmMember     member        = members[ordinal];
                        PrimitiveType primitiveType = (PrimitiveType)member.TypeUsage.EdmType;
                        cmd.ColumnTypes[ordinal] = primitiveType;
                    }
                }
                else if (elementType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType)
                {
                    cmd.ColumnTypes    = new PrimitiveType[1];
                    cmd.ColumnTypes[0] = (PrimitiveType)elementType;
                }
                else
                {
                    Debug.Fail(Resources.WrongFunctionResultType);
                }
            }
        }
        /// <summary>
        /// Ensures we have the command tree, either the user passed us the tree, or an eSQL statement that we need to parse
        /// </summary>
        private void MakeCommandTree()
        {
            // We must have a connection before we come here
            Debug.Assert(this._connection != null);

            // Do the work only if we don't have a command tree yet
            if (this._preparedCommandTree == null)
            {
                DbCommandTree resultTree = null;
                if (this._commandTreeSetByUser != null)
                {
                    resultTree = this._commandTreeSetByUser;
                }
                else
                if (CommandType.Text == CommandType)
                {
                    if (!string.IsNullOrEmpty(this._esqlCommandText))
                    {
                        // The perspective to be used for the query compilation
                        Perspective perspective = (Perspective) new ModelPerspective(_connection.GetMetadataWorkspace());

                        // get a dictionary of names and typeusage from entity parameter collection
                        Dictionary <string, TypeUsage> queryParams = GetParameterTypeUsage();

                        resultTree = CqlQuery.Compile(
                            this._esqlCommandText,
                            perspective,
                            null /*parser option - use default*/,
                            queryParams.Select(paramInfo => paramInfo.Value.Parameter(paramInfo.Key))).CommandTree;
                    }
                    else
                    {
                        // We have no command text, no command tree, so throw an exception
                        if (this._isCommandDefinitionBased)
                        {
                            // This command was based on a prepared command definition and has no command text,
                            // so reprepare is not possible. To create a new command with different parameters
                            // requires creating a new entity command definition and calling it's CreateCommand method.
                            throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.EntityClient_CannotReprepareCommandDefinitionBasedCommand);
                        }
                        else
                        {
                            throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.EntityClient_NoCommandText);
                        }
                    }
                }
                else if (CommandType.StoredProcedure == CommandType)
                {
                    // get a dictionary of names and typeusage from entity parameter collection
                    IEnumerable <KeyValuePair <string, TypeUsage> > queryParams = GetParameterTypeUsage();
                    EdmFunction function = DetermineFunctionImport();
                    resultTree = new DbFunctionCommandTree(this.Connection.GetMetadataWorkspace(), DataSpace.CSpace, function, null, queryParams);
                }

                // After everything is good and succeeded, assign the result to our field
                this._preparedCommandTree = resultTree;
            }
        }
        private static FunctionImportMappingNonComposable GetTargetFunctionMapping(
            DbFunctionCommandTree functionCommandTree)
        {
            FunctionImportMapping targetFunctionMapping;

            if (!functionCommandTree.MetadataWorkspace.TryGetFunctionImportMapping(functionCommandTree.EdmFunction, out targetFunctionMapping))
            {
                throw new InvalidOperationException(Strings.EntityClient_UnmappedFunctionImport((object)functionCommandTree.EdmFunction.FullName));
            }
            return((FunctionImportMappingNonComposable)targetFunctionMapping);
        }
Esempio n. 5
0
        // <summary>
        // Ensures we have the command tree, either the user passed us the tree, or an eSQL statement that we need to parse
        // </summary>
        private DbCommandTree MakeCommandTree()
        {
            // We must have a connection before we come here
            Debug.Assert(_connection != null);

            DbCommandTree resultTree = null;

            if (_commandTreeSetByUser != null)
            {
                resultTree = _commandTreeSetByUser;
            }
            else if (CommandType.Text == CommandType)
            {
                if (!string.IsNullOrEmpty(_esqlCommandText))
                {
                    // The perspective to be used for the query compilation
                    Perspective perspective = new ModelPerspective(_connection.GetMetadataWorkspace());

                    // get a dictionary of names and typeusage from entity parameter collection
                    var queryParams = GetParameterTypeUsage();

                    resultTree = CqlQuery.Compile(
                        _esqlCommandText,
                        perspective,
                        null /*parser option - use default*/,
                        queryParams.Select(paramInfo => paramInfo.Value.Parameter(paramInfo.Key))).CommandTree;
                }
                else
                {
                    // We have no command text, no command tree, so throw an exception
                    if (_isCommandDefinitionBased)
                    {
                        // This command was based on a prepared command definition and has no command text,
                        // so reprepare is not possible. To create a new command with different parameters
                        // requires creating a new entity command definition and calling it's CreateCommand method.
                        throw new InvalidOperationException(Strings.EntityClient_CannotReprepareCommandDefinitionBasedCommand);
                    }
                    else
                    {
                        throw new InvalidOperationException(Strings.EntityClient_NoCommandText);
                    }
                }
            }
            else if (CommandType.StoredProcedure == CommandType)
            {
                // get a dictionary of names and typeusage from entity parameter collection
                IEnumerable <KeyValuePair <string, TypeUsage> > queryParams = GetParameterTypeUsage();
                var function = DetermineFunctionImport();
                resultTree = new DbFunctionCommandTree(Connection.GetMetadataWorkspace(), DataSpace.CSpace, function, null, queryParams);
            }

            return(resultTree);
        }
Esempio n. 6
0
        /// <summary>
        /// General purpose static function that can be called from System.Data assembly
        /// </summary>
        /// <param name="tree">command tree</param>
        /// <param name="version">version</param>
        /// <param name="parameters">Parameters to add to the command tree corresponding
        /// to constants in the command tree. Used only in ModificationCommandTrees.</param>
        /// <returns>The string representing the SQL to be executed.</returns>
        internal static string GenerateSql(DbCommandTree tree, EFIngresStoreVersion version, out List <DbParameter> parameters, out CommandType commandType)
        {
            commandType = CommandType.Text;

            //Handle Query
            DbQueryCommandTree queryCommandTree = tree as DbQueryCommandTree;

            if (queryCommandTree != null)
            {
                SqlGenerator sqlGen = new SqlGenerator(version);
                parameters = null;
                return(sqlGen.GenerateSql((DbQueryCommandTree)tree));
            }

            //Handle Function
            DbFunctionCommandTree DbFunctionCommandTree = tree as DbFunctionCommandTree;

            if (DbFunctionCommandTree != null)
            {
                SqlGenerator sqlGen = new SqlGenerator(version);
                parameters = null;

                string sql = sqlGen.GenerateFunctionSql(DbFunctionCommandTree, out commandType);

                return(sql);
            }

            //Handle Insert
            DbInsertCommandTree insertCommandTree = tree as DbInsertCommandTree;

            if (insertCommandTree != null)
            {
                return(DmlSqlGenerator.GenerateInsertSql(insertCommandTree, out parameters));
            }

            //Handle Delete
            DbDeleteCommandTree deleteCommandTree = tree as DbDeleteCommandTree;

            if (deleteCommandTree != null)
            {
                return(DmlSqlGenerator.GenerateDeleteSql(deleteCommandTree, out parameters));
            }

            //Handle Update
            DbUpdateCommandTree updateCommandTree = tree as DbUpdateCommandTree;

            if (updateCommandTree != null)
            {
                return(DmlSqlGenerator.GenerateUpdateSql(updateCommandTree, out parameters));
            }

            throw new NotSupportedException("Unrecognized command tree type");
        }
        /// <summary>
        /// Retrieves mapping for the given C-Space functionCommandTree
        /// </summary>
        private static FunctionImportMappingNonComposable GetTargetFunctionMapping(DbFunctionCommandTree functionCommandTree)
        {
            Debug.Assert(functionCommandTree.DataSpace == DataSpace.CSpace, "map from CSpace->SSpace function");
            Debug.Assert(functionCommandTree != null, "null functionCommandTree");
            Debug.Assert(!functionCommandTree.EdmFunction.IsComposableAttribute, "functionCommandTree.EdmFunction must be non-composable.");

            // Find mapped store function.
            FunctionImportMapping targetFunctionMapping;

            if (!functionCommandTree.MetadataWorkspace.TryGetFunctionImportMapping(functionCommandTree.EdmFunction, out targetFunctionMapping))
            {
                throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.EntityClient_UnmappedFunctionImport(functionCommandTree.EdmFunction.FullName));
            }
            return((FunctionImportMappingNonComposable)targetFunctionMapping);
        }
Esempio n. 8
0
        internal string Print(DbFunctionCommandTree tree)
        {
            DebugCheck.NotNull(tree);

            var funcNode = new TreeNode("EdmFunction");

            if (tree.EdmFunction != null)
            {
                funcNode.Children.Add(_visitor.VisitFunction(tree.EdmFunction, null));
            }

            var typeNode = new TreeNode("ResultType");

            if (tree.ResultType != null)
            {
                PrinterVisitor.AppendTypeSpecifier(typeNode, tree.ResultType);
            }

            return(Print(new TreeNode("DbFunctionCommandTree", CreateParametersNode(tree), funcNode, typeNode)));
        }
Esempio n. 9
0
        internal string Print(DbFunctionCommandTree tree)
        {
            Debug.Assert(tree != null, "Null DbFunctionCommandTree");

            TreeNode funcNode = new TreeNode("EdmFunction");

            if (tree.EdmFunction != null)
            {
                funcNode.Children.Add(_visitor.VisitFunction(tree.EdmFunction, null));
            }

            TreeNode typeNode = new TreeNode("ResultType");

            if (tree.ResultType != null)
            {
                PrinterVisitor.AppendTypeSpecifier(typeNode, tree.ResultType);
            }

            return(this.Print(new TreeNode("DbFunctionCommandTree", CreateParametersNode(tree), funcNode, typeNode)));
        }
Esempio n. 10
0
        /// <summary>
        /// Translate a function command tree to a SQL string.
        /// </summary>
        private string GenerateFunctionSql(DbFunctionCommandTree tree, out CommandType commandType)
        {
            EdmFunction function = tree.EdmFunction;

            // We expect function to always have these properties
            string userCommandText = (string)function.MetadataProperties["CommandTextAttribute"].Value;
            string userSchemaName  = (string)function.MetadataProperties["Schema"].Value;
            string userFuncName    = (string)function.MetadataProperties["StoreFunctionNameAttribute"].Value;

            if (String.IsNullOrEmpty(userCommandText))
            {
                // build a quoted description of the function
                commandType = CommandType.StoredProcedure;

                // if the schema name is not explicitly given, it is assumed to be the metadata namespace
                string schemaName = String.IsNullOrEmpty(userSchemaName) ?
                                    function.NamespaceName : userSchemaName;

                // if the function store name is not explicitly given, it is assumed to be the metadata name
                string functionName = String.IsNullOrEmpty(userFuncName) ?
                                      function.Name : userFuncName;

                // quote elements of function text
                string quotedSchemaName   = QuoteIdentifier(schemaName);
                string quotedFunctionName = QuoteIdentifier(functionName);

                // separator
                const string schemaSeparator = ".";

                // concatenate elements of function text
                string quotedFunctionText = quotedSchemaName + schemaSeparator + quotedFunctionName;

                return(quotedFunctionText);
            }
            else
            {
                // if the user has specified the command text, pass it through verbatim and choose CommandType.Text
                commandType = CommandType.Text;
                return(userCommandText);
            }
        }
Esempio n. 11
0
        internal string Print(DbFunctionCommandTree tree)
        {
            TreeNode treeNode = new TreeNode("EdmFunction", new TreeNode[0]);

            if (tree.EdmFunction != null)
            {
                treeNode.Children.Add(this._visitor.VisitFunction(tree.EdmFunction, (IList <DbExpression>)null));
            }
            TreeNode node = new TreeNode("ResultType", new TreeNode[0]);

            if (tree.ResultType != null)
            {
                ExpressionPrinter.PrinterVisitor.AppendTypeSpecifier(node, tree.ResultType);
            }
            return(this.Print(new TreeNode("DbFunctionCommandTree", new TreeNode[3]
            {
                ExpressionPrinter.CreateParametersNode((DbCommandTree)tree),
                treeNode,
                node
            })));
        }
        /// <summary>
        /// Sets the expected column types for a given function command tree
        /// </summary>
        private void SetFunctionExpectedTypes(DbFunctionCommandTree tree, EFMySqlCommand cmd)
        {
            if (tree.ResultType != null)
              {
            Debug.Assert(tree.ResultType.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType,
            Resources.WrongFunctionResultType);

            CollectionType collectionType = (CollectionType)(tree.ResultType.EdmType);
            EdmType elementType = collectionType.TypeUsage.EdmType;

            if (elementType.BuiltInTypeKind == BuiltInTypeKind.RowType)
            {
              ReadOnlyMetadataCollection<EdmMember> members = ((RowType)elementType).Members;
              cmd.ColumnTypes = new PrimitiveType[members.Count];

              for (int ordinal = 0; ordinal < members.Count; ordinal++)
              {
            EdmMember member = members[ordinal];
            PrimitiveType primitiveType = (PrimitiveType)member.TypeUsage.EdmType;
            cmd.ColumnTypes[ordinal] = primitiveType;
              }

            }
            else if (elementType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType)
            {
              cmd.ColumnTypes = new PrimitiveType[1];
              cmd.ColumnTypes[0] = (PrimitiveType)elementType;
            }
            else
            {
              Debug.Fail(Resources.WrongFunctionResultType);
            }
              }
        }
        /// <summary>
        /// Create a SampleCommand object, given the provider manifest and command tree
        /// </summary>
        private DbCommand CreateCommand(DbProviderManifest manifest, DbCommandTree commandTree)
        {
            if (manifest == null)
            {
                throw new ArgumentNullException("manifest");
            }

            if (commandTree == null)
            {
                throw new ArgumentNullException("commandTree");
            }

            FbCommand command = new FbCommand();

            #region Type coercions
            // Set expected column types for DbQueryCommandTree
            DbQueryCommandTree queryTree = commandTree as DbQueryCommandTree;
            if (queryTree != null)
            {
                DbProjectExpression projectExpression = queryTree.Query as DbProjectExpression;
                if (projectExpression != null)
                {
                    EdmType resultsType = projectExpression.Projection.ResultType.EdmType;

                    StructuralType resultsAsStructuralType = resultsType as StructuralType;
                    if (resultsAsStructuralType != null)
                    {
                        command.ExpectedColumnTypes = new PrimitiveType[resultsAsStructuralType.Members.Count];

                        for (int ordinal = 0; ordinal < resultsAsStructuralType.Members.Count; ordinal++)
                        {
                            EdmMember     member        = resultsAsStructuralType.Members[ordinal];
                            PrimitiveType primitiveType = member.TypeUsage.EdmType as PrimitiveType;
                            command.ExpectedColumnTypes[ordinal] = primitiveType;
                        }
                    }
                }
            }

            // Set expected column types for DbFunctionCommandTree
            DbFunctionCommandTree functionTree = commandTree as DbFunctionCommandTree;
            if (functionTree != null)
            {
                if (functionTree.ResultType != null)
                {
                    Debug.Assert(MetadataHelpers.IsCollectionType(functionTree.ResultType.EdmType), "Result type of a function is expected to be a collection of RowType or PrimitiveType");

                    EdmType elementType = MetadataHelpers.GetElementTypeUsage(functionTree.ResultType).EdmType;

                    if (MetadataHelpers.IsRowType(elementType))
                    {
                        ReadOnlyMetadataCollection <EdmMember> members = ((RowType)elementType).Members;
                        command.ExpectedColumnTypes = new PrimitiveType[members.Count];

                        for (int ordinal = 0; ordinal < members.Count; ordinal++)
                        {
                            EdmMember     member        = members[ordinal];
                            PrimitiveType primitiveType = (PrimitiveType)member.TypeUsage.EdmType;
                            command.ExpectedColumnTypes[ordinal] = primitiveType;
                        }
                    }
                    else if (MetadataHelpers.IsPrimitiveType(elementType))
                    {
                        command.ExpectedColumnTypes    = new PrimitiveType[1];
                        command.ExpectedColumnTypes[0] = (PrimitiveType)elementType;
                    }
                    else
                    {
                        Debug.Fail("Result type of a function is expected to be a collection of RowType or PrimitiveType");
                    }
                }
            }
            #endregion

            List <DbParameter> parameters;
            CommandType        commandType;

            command.CommandText = SqlGenerator.GenerateSql(commandTree, out parameters, out commandType);
            command.CommandType = commandType;

            // Get the function (if any) implemented by the command tree since this influences our interpretation of parameters
            EdmFunction function = null;
            if (commandTree is DbFunctionCommandTree)
            {
                function = ((DbFunctionCommandTree)commandTree).EdmFunction;
            }

            // Now make sure we populate the command's parameters from the CQT's parameters:
            foreach (KeyValuePair <string, TypeUsage> queryParameter in commandTree.Parameters)
            {
                FbParameter parameter;

                // Use the corresponding function parameter TypeUsage where available (currently, the SSDL facets and
                // type trump user-defined facets and type in the EntityCommand).
                FunctionParameter functionParameter;
                if (null != function && function.Parameters.TryGetValue(queryParameter.Key, false, out functionParameter))
                {
                    parameter = CreateSqlParameter(functionParameter.Name, functionParameter.TypeUsage, functionParameter.Mode, DBNull.Value);
                }
                else
                {
                    parameter = CreateSqlParameter(queryParameter.Key, queryParameter.Value, ParameterMode.In, DBNull.Value);
                }

                command.Parameters.Add(parameter);
            }

            // Now add parameters added as part of SQL gen (note: this feature is only safe for DML SQL gen which
            // does not support user parameters, where there is no risk of name collision)
            if (null != parameters && 0 < parameters.Count)
            {
                if (!(commandTree is DbInsertCommandTree) &&
                    !(commandTree is DbUpdateCommandTree) &&
                    !(commandTree is DbDeleteCommandTree))
                {
                    throw new InvalidOperationException("SqlGenParametersNotPermitted");
                }

                foreach (DbParameter parameter in parameters)
                {
                    command.Parameters.Add(parameter);
                }
            }

            return(command);
        }
 internal EntityCommandDefinition(
     DbProviderFactory storeProviderFactory,
     DbCommandTree commandTree,
     DbInterceptionContext interceptionContext,
     IDbDependencyResolver resolver = null,
     BridgeDataReaderFactory bridgeDataReaderFactory = null,
     ColumnMapFactory columnMapFactory = null)
 {
     this._bridgeDataReaderFactory = bridgeDataReaderFactory ?? new BridgeDataReaderFactory((Translator)null);
     this._columnMapFactory        = columnMapFactory ?? new ColumnMapFactory();
     this._storeProviderServices   = (resolver != null ? resolver.GetService <DbProviderServices>((object)storeProviderFactory.GetProviderInvariantName()) : (DbProviderServices)null) ?? storeProviderFactory.GetProviderServices();
     try
     {
         if (commandTree.CommandTreeKind == DbCommandTreeKind.Query)
         {
             List <ProviderCommandInfo> providerCommands = new List <ProviderCommandInfo>();
             ColumnMap resultColumnMap;
             int       columnCount;
             System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Compile(commandTree, out providerCommands, out resultColumnMap, out columnCount, out this._entitySets);
             this._columnMapGenerators = new EntityCommandDefinition.IColumnMapGenerator[1]
             {
                 (EntityCommandDefinition.IColumnMapGenerator) new EntityCommandDefinition.ConstantColumnMapGenerator(resultColumnMap, columnCount)
             };
             this._mappedCommandDefinitions = new List <DbCommandDefinition>(providerCommands.Count);
             foreach (ProviderCommandInfo providerCommandInfo in providerCommands)
             {
                 DbCommandDefinition commandDefinition = this._storeProviderServices.CreateCommandDefinition(providerCommandInfo.CommandTree, interceptionContext);
                 if (commandDefinition == null)
                 {
                     throw new ProviderIncompatibleException(Strings.ProviderReturnedNullForCreateCommandDefinition);
                 }
                 this._mappedCommandDefinitions.Add(commandDefinition);
             }
         }
         else
         {
             DbFunctionCommandTree functionCommandTree = (DbFunctionCommandTree)commandTree;
             FunctionImportMappingNonComposable targetFunctionMapping = EntityCommandDefinition.GetTargetFunctionMapping(functionCommandTree);
             IList <FunctionParameter>          returnParameters      = (IList <FunctionParameter>)functionCommandTree.EdmFunction.ReturnParameters;
             int length = returnParameters.Count > 1 ? returnParameters.Count : 1;
             this._columnMapGenerators = new EntityCommandDefinition.IColumnMapGenerator[length];
             TypeUsage storeResultType = this.DetermineStoreResultType(targetFunctionMapping, 0, out this._columnMapGenerators[0]);
             for (int resultSetIndex = 1; resultSetIndex < length; ++resultSetIndex)
             {
                 this.DetermineStoreResultType(targetFunctionMapping, resultSetIndex, out this._columnMapGenerators[resultSetIndex]);
             }
             List <KeyValuePair <string, TypeUsage> > keyValuePairList = new List <KeyValuePair <string, TypeUsage> >();
             foreach (KeyValuePair <string, TypeUsage> parameter in functionCommandTree.Parameters)
             {
                 keyValuePairList.Add(parameter);
             }
             this._mappedCommandDefinitions = new List <DbCommandDefinition>(1)
             {
                 this._storeProviderServices.CreateCommandDefinition((DbCommandTree) new DbFunctionCommandTree(functionCommandTree.MetadataWorkspace, DataSpace.SSpace, targetFunctionMapping.TargetFunction, storeResultType, (IEnumerable <KeyValuePair <string, TypeUsage> >)keyValuePairList))
             };
             if (targetFunctionMapping.FunctionImport.EntitySets.FirstOrDefault <EntitySet>() != null)
             {
                 this._entitySets = new Set <EntitySet>();
                 this._entitySets.Add(targetFunctionMapping.FunctionImport.EntitySets.FirstOrDefault <EntitySet>());
                 this._entitySets.MakeReadOnly();
             }
         }
         List <EntityParameter> entityParameterList = new List <EntityParameter>();
         foreach (KeyValuePair <string, TypeUsage> parameter in commandTree.Parameters)
         {
             EntityParameter fromQueryParameter = EntityCommandDefinition.CreateEntityParameterFromQueryParameter(parameter);
             entityParameterList.Add(fromQueryParameter);
         }
         this._parameters = new ReadOnlyCollection <EntityParameter>((IList <EntityParameter>)entityParameterList);
     }
     catch (EntityCommandCompilationException ex)
     {
         throw;
     }
     catch (Exception ex)
     {
         if (ex.IsCatchableExceptionType())
         {
             throw new EntityCommandCompilationException(Strings.EntityClient_CommandDefinitionPreparationFailed, ex);
         }
         throw;
     }
 }
        internal EntityCommandDefinition(
            DbProviderFactory storeProviderFactory, DbCommandTree commandTree, IDbDependencyResolver resolver = null,
            BridgeDataReaderFactory bridgeDataReaderFactory = null, ColumnMapFactory columnMapFactory = null)
        {
            DebugCheck.NotNull(storeProviderFactory);
            DebugCheck.NotNull(commandTree);

            _bridgeDataReaderFactory = bridgeDataReaderFactory ?? new BridgeDataReaderFactory();
            _columnMapFactory        = columnMapFactory ?? new ColumnMapFactory();

            _storeProviderServices =
                (resolver != null
                     ? resolver.GetService <DbProviderServices>(storeProviderFactory.GetProviderInvariantName())
                     : null) ??
                storeProviderFactory.GetProviderServices();

            try
            {
                if (DbCommandTreeKind.Query
                    == commandTree.CommandTreeKind)
                {
                    // Next compile the plan for the command tree
                    var       mappedCommandList = new List <ProviderCommandInfo>();
                    ColumnMap columnMap;
                    int       columnCount;
                    PlanCompiler.Compile(commandTree, out mappedCommandList, out columnMap, out columnCount, out _entitySets);
                    _columnMapGenerators = new IColumnMapGenerator[] { new ConstantColumnMapGenerator(columnMap, columnCount) };
                    // Note: we presume that the first item in the ProviderCommandInfo is the root node;
                    Debug.Assert(mappedCommandList.Count > 0, "empty providerCommandInfo collection and no exception?");
                    // this shouldn't ever happen.

                    // Then, generate the store commands from the resulting command tree(s)
                    _mappedCommandDefinitions = new List <DbCommandDefinition>(mappedCommandList.Count);

                    foreach (var providerCommandInfo in mappedCommandList)
                    {
                        var providerCommandDefinition = _storeProviderServices.CreateCommandDefinition(providerCommandInfo.CommandTree);

                        if (null == providerCommandDefinition)
                        {
                            throw new ProviderIncompatibleException(Strings.ProviderReturnedNullForCreateCommandDefinition);
                        }

                        _mappedCommandDefinitions.Add(providerCommandDefinition);
                    }
                }
                else
                {
                    Debug.Assert(
                        DbCommandTreeKind.Function == commandTree.CommandTreeKind, "only query and function command trees are supported");
                    var entityCommandTree = (DbFunctionCommandTree)commandTree;

                    // Retrieve mapping and metadata information for the function import.
                    var mapping = GetTargetFunctionMapping(entityCommandTree);
                    IList <FunctionParameter> returnParameters = entityCommandTree.EdmFunction.ReturnParameters;
                    var resultSetCount = returnParameters.Count > 1 ? returnParameters.Count : 1;
                    _columnMapGenerators = new IColumnMapGenerator[resultSetCount];
                    var storeResultType = DetermineStoreResultType(mapping, 0, out _columnMapGenerators[0]);
                    for (var i = 1; i < resultSetCount; i++)
                    {
                        DetermineStoreResultType(mapping, i, out _columnMapGenerators[i]);
                    }

                    // Copy over parameters (this happens through a more indirect route in the plan compiler, but
                    // it happens nonetheless)
                    var providerParameters = new List <KeyValuePair <string, TypeUsage> >();
                    foreach (var parameter in entityCommandTree.Parameters)
                    {
                        providerParameters.Add(parameter);
                    }

                    // Construct store command tree usage.
                    var providerCommandTree = new DbFunctionCommandTree(
                        entityCommandTree.MetadataWorkspace, DataSpace.SSpace,
                        mapping.TargetFunction, storeResultType, providerParameters);

                    var storeCommandDefinition = _storeProviderServices.CreateCommandDefinition(providerCommandTree);
                    _mappedCommandDefinitions = new List <DbCommandDefinition>(1)
                    {
                        storeCommandDefinition
                    };

                    var firstResultEntitySet = mapping.FunctionImport.EntitySets.FirstOrDefault();
                    if (firstResultEntitySet != null)
                    {
                        _entitySets = new Set <EntitySet>();
                        _entitySets.Add(mapping.FunctionImport.EntitySets.FirstOrDefault());
                        _entitySets.MakeReadOnly();
                    }
                }

                // Finally, build a list of the parameters that the resulting command should have;
                var parameterList = new List <EntityParameter>();

                foreach (var queryParameter in commandTree.Parameters)
                {
                    var parameter = CreateEntityParameterFromQueryParameter(queryParameter);
                    parameterList.Add(parameter);
                }

                _parameters = new ReadOnlyCollection <EntityParameter>(parameterList);
            }
            catch (EntityCommandCompilationException)
            {
                // No need to re-wrap EntityCommandCompilationException
                throw;
            }
            catch (Exception e)
            {
                // we should not be wrapping all exceptions
                if (e.IsCatchableExceptionType())
                {
                    // we don't wan't folks to have to know all the various types of exceptions that can
                    // occur, so we just rethrow a CommandDefinitionException and make whatever we caught
                    // the inner exception of it.
                    throw new EntityCommandCompilationException(Strings.EntityClient_CommandDefinitionPreparationFailed, e);
                }

                throw;
            }
        }
Esempio n. 16
0
 public VfpExpression Visit(DbFunctionCommandTree commandTree)
 {
     return(new VfpFunctionCommandTree(commandTree.EdmFunction, commandTree.ResultType, commandTree.Parameters));
 }
Esempio n. 17
0
 public SqlFunctionGenerator(DbFunctionCommandTree commandTree)
 {
     _commandTree = commandTree;
 }