/// <summary>
        /// Compiles eSQL <paramref name="functionDefinition"/> and returns <see cref="DbLambda"/>.
        /// Guarantees type match of lambda variables and <paramref name="functionParameters"/>.
        /// Passes thru all excepions coming from <see cref="CqlQuery"/>.
        /// </summary>
        internal static DbLambda CompileFunctionDefinition(
            string functionDefinition,
            IList<FunctionParameter> functionParameters,
            EdmItemCollection edmItemCollection)
        {
            Debug.Assert(functionParameters != null, "functionParameters != null");
            Debug.Assert(edmItemCollection != null, "edmItemCollection != null");

            var workspace = new MetadataWorkspace();
            workspace.RegisterItemCollection(edmItemCollection);
            Perspective perspective = new ModelPerspective(workspace);

            // Since we compile lambda expression and generate variables from the function parameter definitions,
            // the returned DbLambda will contain variable types that match function parameter types.
            var functionBody = CqlQuery.CompileQueryCommandLambda(
                functionDefinition,
                perspective,
                null /* use default parser options */,
                null /* parameters */,
                functionParameters.Select(pInfo => pInfo.TypeUsage.Variable(pInfo.Name)));
            Debug.Assert(functionBody != null, "functionBody != null");

            return functionBody;
        }
 /// <summary>
 /// Creates a new instance of perspective class so that query can work
 /// ignorant of all spaces
 /// </summary>
 /// <param name="metadataWorkspace">runtime metadata container</param>
 internal TargetPerspective(MetadataWorkspace metadataWorkspace)
     : base(metadataWorkspace, TargetPerspective.TargetPerspectiveDataSpace)
 {
     _modelPerspective = new ModelPerspective(metadataWorkspace);
 }
 /// <summary>
 /// Creates a new instance of perspective class so that query can work
 /// ignorant of all spaces
 /// </summary>
 /// <param name="metadataWorkspace">runtime metadata container</param>
 internal TargetPerspective(MetadataWorkspace metadataWorkspace)
     : base(metadataWorkspace, TargetPerspective.TargetPerspectiveDataSpace)
 {
     _modelPerspective = new ModelPerspective(metadataWorkspace);
 }
        /// <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(_connection != null);

            // Do the work only if we don't have a command tree yet
            if (_preparedCommandTree == 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);
                }

                // After everything is good and succeeded, assign the result to our field
                _preparedCommandTree = resultTree;
            }
        }