RelationalExpressions.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Common / CommandTrees / RelationalExpressions.cs / 3 / RelationalExpressions.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....], [....]
//--------------------------------------------------------------------- 
 
using System;
using System.Collections.Generic; 
using System.Globalization;
using System.Diagnostics;

using System.Data.Common; 
using System.Data.Metadata.Edm;
using System.Data.Common.CommandTrees.Internal; 
 
namespace System.Data.Common.CommandTrees
{ 
    /// 
    /// Represents an apply operation, which is the invocation of the specified functor for each element in the specified input set.
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbApplyExpression : DbExpression
    { 
        DbExpressionBinding m_input; 
        DbExpressionBinding m_apply;
 
        internal DbApplyExpression(DbCommandTree cmdTree,
            DbExpressionBinding input,
            DbExpressionBinding apply, DbExpressionKind applyKind)
            : base(cmdTree, applyKind) 
        {
            // 
            // Validate and initialize the input expression binding 
            //
            DbExpressionBinding.Check("Input", input, cmdTree); 
            m_input = input;

            //
            // Validate and initialize the apply expression binding 
            //
            DbExpressionBinding.Check("Apply", apply, cmdTree); 
            m_apply = apply; 

            // 
            // Duplicate Input and Apply binding names are not allowed
            //
            if (input.VariableName.Equals(apply.VariableName, StringComparison.Ordinal))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Apply_DuplicateVariableNames);
            } 
 
            //
            // Validate the DbExpressionKind is correct for DbApplyExpression 
            //
            Debug.Assert(DbExpressionKind.CrossApply == applyKind || DbExpressionKind.OuterApply == applyKind, "Invalid DbExpressionKind for DbApplyExpression");

            // 
            // Initialize the result type
            // 
            List> recordCols = new List>(); 
            recordCols.Add(new KeyValuePair(this.m_input.VariableName, this.m_input.VariableType));
            recordCols.Add(new KeyValuePair(this.m_apply.VariableName, this.m_apply.VariableType)); 

            this.ResultType = CommandTreeTypeHelper.CreateCollectionOfRowResultType(recordCols);
        }
 
        /// 
        /// Gets the  that specifies the functor that is invoked for each element in the input set. 
        ///  
        public DbExpressionBinding Apply
        { 
            get { return m_apply;  }
        }

        ///  
        /// Gets the  that specifies the input set.
        ///  
        public DbExpressionBinding Input { get { return m_input; } } 

        ///  
        /// The visitor pattern method for expression visitors that do not produce a result value.
        /// 
        /// An instance of DbExpressionVisitor.
        ///  is null 
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
 
        ///  
        /// The visitor pattern method for expression visitors that produce a result value of a specific type.
        ///  
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.
        /// The type of the result produced by 
        ///  is null
        /// An instance of . 
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
    } 
 
    /// 
    /// Represents the removal of duplicate elements from the specified set operand. 
    /// 
    /// 
    /// DbDistinctExpression requires that its argument has a collection result type
    /// with an element type that is equality comparable. 
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbDistinctExpression : DbUnaryExpression 
    {
        internal DbDistinctExpression(DbCommandTree cmdTree, DbExpression arg) 
            : base(cmdTree, DbExpressionKind.Distinct, arg)
        {
            //
            // Ensure that the Argument is of a collection type 
            //
            this.CheckCollectionArgument(); 
 
            //
            // Ensure that the Distinct operation is valid for the input 
            //
            CollectionType inputType = TypeHelpers.GetEdmType(arg.ResultType);
            if (!TypeHelpers.IsValidDistinctOpType(inputType.TypeUsage))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Distinct_InvalidCollection, "Argument");
            } 
 
            //
            // Result Type is the same collection type as the input 
            //
            this.ResultType = arg.ResultType;
        }
 
        /// 
        /// The visitor pattern method for expression visitors that do not produce a result value. 
        ///  
        /// An instance of DbExpressionVisitor.
        ///  is null 
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }

        /// 
        /// The visitor pattern method for expression visitors that produce a result value of a specific type. 
        /// 
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. 
        /// The type of the result produced by  
        ///  is null
        /// An instance of . 
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
    }

    ///  
    /// Represents the conversion of the specified set operand to a singleton.
    ///  
    ///  
    /// DbElementExpression requires that its argument has a collection result type
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbElementExpression : DbUnaryExpression
    {
        private bool _singlePropertyUnwrapped; 

        internal DbElementExpression(DbCommandTree cmdTree, DbExpression arg, bool unwrapSingleProperty) 
            : base(cmdTree, DbExpressionKind.Element, arg) 
        {
            // 
            // Ensure that the operand is actually of a collection type.
            //
            this.CheckCollectionArgument();
 
            _singlePropertyUnwrapped = unwrapSingleProperty;
 
            // 
            // Result Type is the element type of the collection type
            // 
            TypeUsage resultType = TypeHelpers.GetEdmType(arg.ResultType).TypeUsage;

            //
            // If needed, change the result type of the element expression to the type of the 
            // single property of the element of its operand
            // 
            if (unwrapSingleProperty) 
            {
                IList properties = TypeHelpers.GetProperties(resultType); 
                if (properties == null || properties.Count != 1)
                {
                    throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Element_InvalidArgumentForUnwrapSingleProperty, "arg");
                } 
                resultType = properties[0].TypeUsage;
            } 
 
            this.ResultType = resultType;
        } 

        /// 
        /// Is the result type of the element equal to the result type of the single property
        /// of the element of its operand? 
        /// 
        internal bool IsSinglePropertyUnwrapped { get { return _singlePropertyUnwrapped; } } 
 
        /// 
        /// The visitor pattern method for expression visitors that do not produce a result value. 
        /// 
        /// An instance of DbExpressionVisitor.
        ///  is null
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 

        ///  
        /// The visitor pattern method for expression visitors that produce a result value of a specific type. 
        /// 
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. 
        /// The type of the result produced by 
        ///  is null
        /// An instance of .
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 
    }
 
    ///  
    /// Represents the set subtraction operation between the left and right operands.
    ///  
    /// 
    /// DbExceptExpression requires that its arguments have a common collection result type
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbExceptExpression : DbBinaryExpression
    { 
        internal DbExceptExpression(DbCommandTree cmdTree, DbExpression left, DbExpression right) 
            : base(cmdTree, DbExpressionKind.Except, left, right)
        { 
            //
            // Ensure that the left and right operands are each of a collection type and that a common type exists for those types.
            //
            this.CheckCollectionArguments(); 

            // 
            // ensures arguments types are valid for EXCEPT 
            //
            this.CheckComparableSetArguments(); 

            //
            // Left Except Right produces a result with the same type as the Left operand
            // A Left operand with Type NullType is not allowed. 
            //
            if (TypeSemantics.IsNullType(this.Left.ResultType)) 
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Except_LeftNullTypeInvalid, "Left");
            } 

            this.ResultType = this.Left.ResultType;
        }
 
        /// 
        /// The visitor pattern method for expression visitors that do not produce a result value. 
        ///  
        /// An instance of DbExpressionVisitor.
        ///  is null 
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }

        /// 
        /// The visitor pattern method for expression visitors that produce a result value of a specific type. 
        /// 
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. 
        /// The type of the result produced by  
        ///  is null
        /// An instance of . 
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
    }

    ///  
    /// Represents a predicate applied to an input set to produce the set of elements that satisfy the predicate.
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbFilterExpression : DbExpression
    { 
        DbExpressionBinding _input;
        ExpressionLink _predicate;

        internal DbFilterExpression(DbCommandTree cmdTree, DbExpressionBinding input, DbExpression predExpr) 
            : base(cmdTree, DbExpressionKind.Filter)
        { 
            _predicate = new ExpressionLink("Predicate", cmdTree, PrimitiveTypeKind.Boolean, predExpr); 

            DbExpressionBinding.Check("Input", input, cmdTree); 
            _input = input;
            this.ResultType = _input.Expression.ResultType;
        }
 
        /// 
        /// Gets the  that specifies the input set. 
        ///  
        public DbExpressionBinding Input { get { return _input; } }
 
        /// 
        /// Gets or sets the  that specifies the predicate used to filter the input set.
        /// 
        /// The expression is null 
        /// 
        ///     The expression is not associated with the DbFilterExpression's command tree, 
        ///     or its result type is not a Boolean type. 
        /// 
        public DbExpression Predicate { get { return _predicate.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _predicate.Expression = value; } } 

        /// 
        /// The visitor pattern method for expression visitors that do not produce a result value.
        ///  
        /// An instance of DbExpressionVisitor.
        ///  is null 
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 

        ///  
        /// The visitor pattern method for expression visitors that produce a result value of a specific type.
        /// 
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.
        /// The type of the result produced by  
        ///  is null
        /// An instance of . 
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 
    }
 
    /// 
    /// Represents a group by operation, which is a grouping of the elements in the input set based on the specified key expressions followed by the application of the specified aggregates.
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbGroupByExpression : DbExpression
    { 
        private DbGroupExpressionBinding _input; 
        private IList _keys;
        private IList _aggregates; 

        internal DbGroupByExpression(DbCommandTree cmdTree,
                                    DbGroupExpressionBinding input,
                                    IList> groupKeys, 
                                    IList> aggregates)
            : base(cmdTree, DbExpressionKind.GroupBy) 
        { 
            List colNames = new List();
            List> columns = new List>(); 

            List keys = new List();
            List aggs = new List();
 
            //
            // Validate the input set 
            // 
            DbGroupExpressionBinding.Check("Input", input, cmdTree);
 
            //
            // Validate the grouping keys
            //
            CommandTreeUtils.CheckNamedList 
            (
                "groupKeys", 
                groupKeys, 
                true, // Allow empty list
                delegate(KeyValuePair keyInfo, int index) 
                {
                    //
                    // The result Type of an expression used as a group key must be equality comparable
                    // 
                    if (!TypeHelpers.IsValidGroupKeyType(keyInfo.Value.ResultType))
                    { 
                        throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_GroupBy_KeyNotEqualityComparable(keyInfo.Key)); 
                    }
 
                    keys.Add(keyInfo.Value);

                    //
                    // Track the cumulative set of column names 
                    //
                    colNames.Add(keyInfo.Key); 
 
                    columns.Add(new KeyValuePair(keyInfo.Key, keyInfo.Value.ResultType));
                } 
            );

            //
            // Validate the aggregates 
            //
            CommandTreeUtils.CheckNamedList 
            ( 
                "aggregates",
                aggregates, 
                true, // Allow empty list
                delegate(KeyValuePair aggInfo, int idx)
                {
                    if (aggInfo.Value.CommandTree != cmdTree) 
                    {
                        throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_GroupBy_AggregateTreeMismatch); 
                    } 

                    // 
                    // Is there a grouping key with the same name?
                    //
                    if (colNames.Contains(aggInfo.Key))
                    { 
                        throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_GroupBy_AggregateColumnExistsAsGroupColumn(aggInfo.Key));
                    } 
 
                    aggs.Add(aggInfo.Value);
                    columns.Add(new KeyValuePair(aggInfo.Key, aggInfo.Value.ResultType)); 
                }
            );

            // 
            // Either the Keys or Aggregates may be omitted, but not both
            // 
            if (0 == keys.Count && 0 == aggs.Count) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_GroupBy_AtLeastOneKeyOrAggregate); 
            }

            //
            // Initialize member variables. Group keys are read-write/fixed size, type-immutable, aggregates are read-only (but their arguments are read-write type-immutable) 
            //
            _input = input; 
            _keys = new ExpressionList("Keys", cmdTree, keys); 
            _aggregates = aggs.AsReadOnly();
 
            //
            // Create the result type. This is a collection of the record type produced by the group keys and aggregates.
            //
            this.ResultType = CommandTreeTypeHelper.CreateCollectionOfRowResultType(columns); 
        }
 
        ///  
        /// Gets the  that specifies the input set and provides access to the set element and group element variables.
        ///  
        public DbGroupExpressionBinding Input { get { return _input; } }

        /// 
        /// Gets an  list that provides grouping keys. 
        /// 
        public IList Keys { get { return _keys; } } 
 
        /// 
        /// Gets an  list that provides the aggregates to apply. 
        /// 
        public IList Aggregates { get { return _aggregates; } }

        ///  
        /// The visitor pattern method for expression visitors that do not produce a result value.
        ///  
        /// An instance of DbExpressionVisitor. 
        ///  is null
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 

        /// 
        /// The visitor pattern method for expression visitors that produce a result value of a specific type.
        ///  
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.
        /// The type of the result produced by  
        ///  is null 
        /// An instance of .
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 
    }

    /// 
    /// Represents the set intersection operation between the left and right operands. 
    /// 
    ///  
    /// DbIntersectExpression requires that its arguments have a common collection result type 
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbIntersectExpression : DbBinaryExpression
    {
        internal DbIntersectExpression(DbCommandTree cmdTree, DbExpression left, DbExpression right)
            : base(cmdTree, DbExpressionKind.Intersect, left, right) 
        {
            // 
            // Ensure that the left and right operands are each of a collection type and that a common type exists for those types. 
            //
            this.ResultType = this.CheckCollectionArguments(); 

            //
            // ensures arguments types are valid for INTERSECT
            // 
            this.CheckComparableSetArguments();
        } 
 
        /// 
        /// The visitor pattern method for expression visitors that do not produce a result value. 
        /// 
        /// An instance of DbExpressionVisitor.
        ///  is null
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 

        ///  
        /// The visitor pattern method for expression visitors that produce a result value of a specific type. 
        /// 
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. 
        /// The type of the result produced by 
        ///  is null
        /// An instance of .
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 
    }
 
    ///  
    /// Represents an unconditional join operation between the given collection arguments
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbCrossJoinExpression : DbExpression
    {
        private IList _inputs; 

        internal DbCrossJoinExpression(DbCommandTree cmdTree, IList inputs) 
            : base(cmdTree, DbExpressionKind.CrossJoin) 
       {
            // 
            // Ensure that the list of input expression bindings is non-null.
            //
            EntityUtil.CheckArgumentNull(inputs, "inputs");
 
            //
            // Validate the input expression bindings and build the column types for the record type 
            // component of the collection of record type result type of the join. 
            //
            List inputList = new List(inputs.Count); 
            List> columns = new List>(inputs.Count);
            Dictionary bindingNames = new Dictionary();
            for (int iPos = 0; iPos < inputs.Count; iPos++)
            { 
                DbExpressionBinding input = inputs[iPos];
 
                // 
                // Validate the DbExpressionBinding before accessing its properties
                // 
                DbExpressionBinding.Check(CommandTreeUtils.FormatIndex("Inputs", iPos), input, cmdTree);

                //
                // Duplicate binding names are not allowed 
                //
                int nameIndex = -1; 
                if(bindingNames.TryGetValue(input.VariableName, out nameIndex)) 
                {
                    throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_CrossJoin_DuplicateVariableNames(nameIndex, iPos, input.VariableName)); 
                }

                inputList.Add(input);
                bindingNames.Add(input.VariableName, iPos); 

                columns.Add(new KeyValuePair(input.VariableName, input.VariableType)); 
            } 

            if (inputList.Count < 2) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_CrossJoin_AtLeastTwoInputs, "inputs");
            }
 
            //
            // Initialize state 
            // 
            _inputs = inputList.AsReadOnly();
 
            //
            // Initialize the result type
            //
            this.ResultType = CommandTreeTypeHelper.CreateCollectionOfRowResultType(columns); 
       }
 
        ///  
        /// Gets an  list that provide the input sets to the join.
        ///  
        public IList Inputs { get { return _inputs; } }

        /// 
        /// The visitor pattern method for expression visitors that do not produce a result value. 
        /// 
        /// An instance of DbExpressionVisitor. 
        ///  is null 
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
 
        /// 
        /// The visitor pattern method for expression visitors that produce a result value of a specific type.
        /// 
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. 
        /// The type of the result produced by 
        ///  is null 
        /// An instance of . 
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
    } 

    /// 
    /// Represents an inner, left outer or full outer join operation between the given collection arguments on the specified join condition.
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbJoinExpression : DbExpression 
    { 
        private DbExpressionBinding _left;
        private DbExpressionBinding _right; 
        private ExpressionLink _cond;

        internal DbJoinExpression(DbCommandTree cmdTree, DbExpressionKind joinKind, DbExpressionBinding left, DbExpressionBinding right, DbExpression joinCond)
            : base(cmdTree, joinKind) 
        {
            Debug.Assert(DbExpressionKind.InnerJoin == joinKind || 
                         DbExpressionKind.LeftOuterJoin == joinKind || 
                         DbExpressionKind.FullOuterJoin == joinKind,
                         "Invalid DbExpressionKind specified for DbJoinExpression"); 

            //
            // Validate
            // 
            DbExpressionBinding.Check("Left", left, cmdTree);
            DbExpressionBinding.Check("Right", right, cmdTree); 
 
            //
            // Duplicate Left and Right binding names are not allowed 
            //
            if (left.VariableName.Equals(right.VariableName, StringComparison.Ordinal))
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Join_DuplicateVariableNames); 
            }
 
            // 
            // Initialize state (this also validates the JoinCondition)
            // 
            _left = left;
            _right = right;
            _cond = new ExpressionLink("JoinCondition", cmdTree, PrimitiveTypeKind.Boolean, joinCond);
 
            //
            // Initialize the result type 
            // 
            List> columns = new List>(2);
            columns.Add(new KeyValuePair(left.VariableName, left.VariableType)); 
            columns.Add(new KeyValuePair(right.VariableName, right.VariableType));

            this.ResultType = CommandTreeTypeHelper.CreateCollectionOfRowResultType(columns);
        } 

        ///  
        /// Gets the  provides the left input. 
        /// 
        public DbExpressionBinding Left { get { return _left; } } 

        /// 
        /// Gets the  provides the right input.
        ///  
        public DbExpressionBinding Right { get { return _right; } }
 
        ///  
        /// Gets or sets the optional join condition to apply.
        ///  
        /// The expression is null
        /// 
        ///     The expression is not associated with the DbJoinExpression's command tree,
        ///     or its result type is not a Boolean type. 
        /// 
        public DbExpression JoinCondition 
        { 
            get { return _cond.Expression; }
            /*CQT_PUBLIC_API(*/internal/*)*/ set 
            {
                _cond.Expression = value;
            }
        } 

        ///  
        /// The visitor pattern method for expression visitors that do not produce a result value. 
        /// 
        /// An instance of DbExpressionVisitor. 
        ///  is null
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }

        ///  
        /// The visitor pattern method for expression visitors that produce a result value of a specific type.
        ///  
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. 
        /// The type of the result produced by 
        ///  is null 
        /// An instance of .
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
    }
 
    /// 
    /// Represents the restriction of the number of elements in the Argument collection to the specified Limit value. 
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbLimitExpression : DbExpression 
    {
        private ExpressionLink _argument;
        private ExpressionLink _limit;
        private bool _withTies; 

        internal DbLimitExpression(DbCommandTree commandTree, DbExpression argument, DbExpression limit, bool withTies) 
            : base(commandTree, DbExpressionKind.Limit) 
        {
            // 
            // Initialize the Argument ExpressionLink. In addition to being non-null and from the same command tree,
            // the Argument expression must have a collection result type.
            //
            _argument = new ExpressionLink("Argument", commandTree, argument); 
            if (!TypeSemantics.IsCollectionType(argument.ResultType))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Unary_CollectionRequired(this.GetType().Name), "Argument"); 
            }
 
            //
            // Initialize the Limit ExpressionLink. In addition to being non-null and from the same command tree,
            // the Limit expression must also have an integer result type.
            // 
            _limit = new ExpressionLink("Limit", commandTree, limit);
            if (!TypeSemantics.IsIntegerNumericType(_limit.Expression.ResultType)) 
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Limit_IntegerRequired, "Limit");
            } 

            //
            // Currently the Limit expression is also required to be either a DbConstantExpression or a DbParameterReferenceExpression.
            // 
            if (limit.ExpressionKind != DbExpressionKind.Constant &&
                limit.ExpressionKind != DbExpressionKind.ParameterReference) 
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Limit_ConstantOrParameterRefRequired, "Limit");
            } 

            //
            // For constants, verify the limit is non-negative.
            // 
            if (CommandTreeTypeHelper.IsConstantNegativeInteger(limit))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Limit_NonNegativeLimitRequired, "Limit"); 
            }
 
            // Initalize the 'With Ties' property from the _withTies argument.
            _withTies = withTies;

            // 
            // Initialize the result type. The ResultType of DbLimitExpression is the same as the result type of its argument.
            // 
            this.ResultType = _argument.Expression.ResultType; 
        }
 
        /// 
        /// Gets or sets an expression that specifies the input collection.
        /// 
        /// The expression is null 
        /// 
        ///     The expression is not associated with the DbLimitExpression's command tree, 
        ///     or its result type is not a collection type. 
        /// 
        public DbExpression Argument 
        {
            get { return _argument.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _argument.Expression = value; }
        }
 
        /// 
        /// Gets or sets an expression that specifies the limit on the number of elements returned from the input collection. 
        ///  
        /// The expression is null
        ///  
        ///     The expression is not associated with the DbLimitExpression's command tree,
        ///     or is not one of  or ,
        ///     or its result type is not equal or promotable to a 64-bit integer type.
        ///  
        public DbExpression Limit
        { 
            get { return _limit.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _limit.Expression = value; } 
        }
 
        /// 
        /// Gets whether the limit operation will include tied results, which could produce more results than specifed by the Limit value if ties are present.
        /// 
        public bool WithTies { get { return _withTies; } } 

        ///  
        /// The visitor pattern method for expression visitors that do not produce a result value. 
        /// 
        /// An instance of DbExpressionVisitor. 
        ///  is null
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }

        ///  
        /// The visitor pattern method for expression visitors that produce a result value of a specific type.
        ///  
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. 
        /// The type of the result produced by 
        ///  is null 
        /// An instance of .
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
    }
 
    /// 
    /// Represents the projection of a given set of values over the specified input set. 
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbProjectExpression : DbExpression 
    {
        DbExpressionBinding _input;
        ExpressionLink _proj;
 
        internal DbProjectExpression(DbCommandTree cmdTree, DbExpressionBinding input, DbExpression projection)
            : base(cmdTree, DbExpressionKind.Project) 
        { 
            DbExpressionBinding.Check("Input", input, cmdTree);
            _input = input; 

            _proj = new ExpressionLink("Projection", cmdTree, projection);

            // 
            // Project produces a collection with an element type corresponding to the Type produced by the projection expression.
            // 
            this.ResultType = CommandTreeTypeHelper.CreateCollectionResultType(this.Projection.ResultType); 
        }
 
        /// 
        /// Gets the  that specifies the input set.
        /// 
        public DbExpressionBinding Input { get { return _input; } } 

        ///  
        /// Gets or sets the  that defines the projection. 
        /// 
        /// The expression is null 
        /// 
        ///     The expression is not associated with the DbProjectExpression's command tree,
        ///     or its result type is not equal or promotable to the result type of the current projection.
        ///  
        public DbExpression Projection { get { return _proj.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _proj.Expression = value; } }
 
        ///  
        /// The visitor pattern method for expression visitors that do not produce a result value.
        ///  
        /// An instance of DbExpressionVisitor.
        ///  is null
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
 
        /// 
        /// The visitor pattern method for expression visitors that produce a result value of a specific type. 
        ///  
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.
        /// The type of the result produced by  
        ///  is null
        /// An instance of .
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
    } 

    ///  
    /// Represents a quantifier operation of the specified kind (Any, All) over the elements of the specified input set. 
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbQuantifierExpression : DbExpression
    {
        DbExpressionBinding _input;
        ExpressionLink _pred; 

        internal DbQuantifierExpression(DbCommandTree cmdTree, DbExpressionKind kind, 
            DbExpressionBinding input, DbExpression pred) 
            : base(cmdTree, kind)
        { 
            DbExpressionBinding.Check("Input", input, cmdTree);
            _input = input;

            _pred = new ExpressionLink("Predicate", cmdTree, PrimitiveTypeKind.Boolean, pred); 

            this.ResultType = cmdTree.TypeHelper.CreateBooleanResultType(); 
        } 

        ///  
        /// Gets the  that specifies the input set.
        /// 
        public DbExpressionBinding Input { get { return _input; } }
 
        /// 
        /// Gets or sets the Boolean predicate that should be evaluated for each element in the input set. 
        ///  
        /// The expression is null
        ///  
        ///     The expression is not associated with the DbQuantifierExpression's command tree,
        ///     or its result type is not a Boolean type.
        /// 
        public DbExpression Predicate { get { return _pred.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _pred.Expression = value; } } 

        ///  
        /// The visitor pattern method for expression visitors that do not produce a result value. 
        /// 
        /// An instance of DbExpressionVisitor. 
        ///  is null
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }

        ///  
        /// The visitor pattern method for expression visitors that produce a result value of a specific type.
        ///  
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. 
        /// The type of the result produced by 
        ///  is null 
        /// An instance of .
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
    }
 
    /// 
    /// Specifies a sort key that can be used as part of the sort order in a DbSortExpression. 
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbSortClause 
    {
        private ExpressionLink _expr;
        private bool _asc;
        private string _coll; 

        internal DbSortClause(DbExpression key, bool asc, string collation) 
        { 
            if (null == key)
            { 
                throw EntityUtil.ArgumentNull("key");
            }

            _expr = new ExpressionLink("Expression", key.CommandTree, key); 
            if (!TypeHelpers.IsValidSortOpKeyType(this.Expression.ResultType))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Sort_OrderComparable, "key"); 
            }
 
            if(!string.IsNullOrEmpty(collation) && !TypeSemantics.IsPrimitiveType(this.Expression.ResultType, PrimitiveTypeKind.String))
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Sort_NonStringCollationInvalid, "collation");
            } 

            _asc = asc; 
            _coll = collation; 
        }
 
        /// 
        /// Gets a Boolean value indicating whether or not this sort key is sorted ascending.
        /// 
        public bool Ascending { get { return _asc; } } 

        ///  
        /// Gets a string value that specifies the collation for this sort key. 
        /// 
        public string Collation { get { return _coll; } } 

        /// 
        /// Gets or sets the  that provides the value for this sort key.
        ///  
        /// The expression is null
        ///  
        ///     The expression is not associated with the DbSortClause's command tree, 
        ///     or its result type is not equal or promotable to the result type
        ///     of the current value of the property. 
        /// 
        public DbExpression Expression { get { return _expr.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _expr.Expression = value; } }
    }
 
    /// 
    /// Represents a skip operation of the specified number of elements of the input set after the ordering described in the given sort keys is applied. 
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbSkipExpression : DbExpression 
    {
        private DbExpressionBinding _input;
        private IList _keys;
        private ExpressionLink _count; 

        internal DbSkipExpression(DbCommandTree commandTree, DbExpressionBinding input, IList sortOrder, DbExpression count) 
            : base(commandTree, DbExpressionKind.Skip) 
        {
            // 
            // Perform common Sort argument validation
            //
            DbSortExpression.CheckSortArguments(commandTree, input, sortOrder);
            _input = input; 
            _keys = CommandTreeUtils.NewReadOnlyList(sortOrder);
 
            // 
            // Initialize the Count ExpressionLink. In addition to being non-null and from the same command tree,
            // the Count expression must also have an integer result type. 
            //
            _count = new ExpressionLink("Count", commandTree, count);
            if (!TypeSemantics.IsIntegerNumericType(_count.Expression.ResultType))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Skip_IntegerRequired, "Count");
            } 
 
            //
            // Currently the Count expression is also required to be either a DbConstantExpression or a DbParameterReferenceExpression. 
            //
            if (count.ExpressionKind != DbExpressionKind.Constant &&
                count.ExpressionKind != DbExpressionKind.ParameterReference)
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Skip_ConstantOrParameterRefRequired, "Count");
            } 
 
            //
            // For constants, verify the count is non-negative. 
            //
            if (CommandTreeTypeHelper.IsConstantNegativeInteger(count))
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Skip_NonNegativeCountRequired, "Count"); 
            }
 
            this.ResultType = _input.Expression.ResultType; 
        }
 
        /// 
        /// Gets the  that specifies the input set.
        /// 
        public DbExpressionBinding Input { get { return _input; } } 

        ///  
        /// Gets a  list that defines the sort order. 
        /// 
        public IList SortOrder { get { return _keys; } } 

        /// 
        /// Gets or sets an expression that specifies the number of elements from the input collection to skip.
        ///  
        /// The expression is null
        ///  
        ///     The expression is not associated with the DbSkipExpression's command tree, 
        ///     or is not one of  or ,
        ///     or its result type is not equal or promotable to a 64-bit integer type. 
        /// 
        public DbExpression Count
        {
            get { return _count.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _count.Expression = value; } 
        }
 
        ///  
        /// The visitor pattern method for expression visitors that do not produce a result value.
        ///  
        /// An instance of DbExpressionVisitor.
        ///  is null
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
 
        /// 
        /// The visitor pattern method for expression visitors that produce a result value of a specific type. 
        ///  
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.
        /// The type of the result produced by  
        ///  is null
        /// An instance of .
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
    } 

    ///  
    /// Represents a sort operation applied to the elements of the specified input set based on the given sort keys. 
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbSortExpression : DbExpression
    {
        private DbExpressionBinding _input;
        private IList _keys; 

        internal DbSortExpression(DbCommandTree cmdTree, DbExpressionBinding input, IList sortOrder) 
            : base(cmdTree,DbExpressionKind.Sort) 
        {
            DbSortExpression.CheckSortArguments(cmdTree, input, sortOrder); 

            _input = input;
            _keys = CommandTreeUtils.NewReadOnlyList(sortOrder);
 
            this.ResultType = input.Expression.ResultType;
        } 
 
        /// 
        /// Gets the  that specifies the input set. 
        /// 
        public DbExpressionBinding Input { get { return _input; } }

        ///  
        /// Gets a  list that defines the sort order.
        ///  
        public IList SortOrder { get { return _keys; } } 

        ///  
        /// The visitor pattern method for expression visitors that do not produce a result value.
        /// 
        /// An instance of DbExpressionVisitor.
        ///  is null 
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
 
        ///  
        /// The visitor pattern method for expression visitors that produce a result value of a specific type.
        ///  
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.
        /// The type of the result produced by 
        ///  is null
        /// An instance of . 
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
 
        ///  
        /// Validates the input and sort key arguments to both DbSkipExpression and DbSortExpression.
        ///  
        /// The Command Tree used to create the new Skip or Sort DbExpression
        /// A DbExpressionBinding that provides the collection to be ordered
        /// A list of SortClauses that specifies the sort order to apply to the input collection
        internal static void CheckSortArguments(DbCommandTree cmdTree, DbExpressionBinding input, IList keys) 
        {
            // 
            // Validate the Input 
            //
            DbExpressionBinding.Check("Input", input, cmdTree); 

            //
            // Validate the Sort keys
            // 
            EntityUtil.CheckArgumentNull(keys, "SortOrder");
            if (keys.Count < 1) 
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_SkipSort_AtLeastOneKey, "SortOrder");
            } 

            for (int idx = 0; idx < keys.Count; idx++)
            {
                DbSortClause key = keys[idx]; 

                if (null == key) 
                { 
                    throw EntityUtil.ArgumentNull(CommandTreeUtils.FormatIndex("SortOrder", idx));
                } 

                if (!object.ReferenceEquals(key.Expression.CommandTree, cmdTree))
                {
                    throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_General_TreeMismatch, CommandTreeUtils.FormatIndex("SortOrder", idx)); 
                }
            } 
        } 
    }
 
    /// 
    /// Represents the set union (without duplicate removal) operation between the left and right operands.
    /// 
    ///  
    /// DbUnionAllExpression requires that its arguments have a common collection result type
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbUnionAllExpression : DbBinaryExpression
    { 
        internal DbUnionAllExpression(DbCommandTree cmdTree, DbExpression left, DbExpression right)
            : base(cmdTree, DbExpressionKind.UnionAll, left, right)
        {
            // 
            // Ensure that the left and right operands are each of a collection type and that a common type exists for those types.
            // 
            this.ResultType = this.CheckCollectionArguments(); 
        }
 
        /// 
        /// The visitor pattern method for expression visitors that do not produce a result value.
        /// 
        /// An instance of DbExpressionVisitor. 
        ///  is null
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 
 
        /// 
        /// The visitor pattern method for expression visitors that produce a result value of a specific type. 
        /// 
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.
        /// The type of the result produced by 
        ///  is null 
        /// An instance of .
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....], [....]
//--------------------------------------------------------------------- 
 
using System;
using System.Collections.Generic; 
using System.Globalization;
using System.Diagnostics;

using System.Data.Common; 
using System.Data.Metadata.Edm;
using System.Data.Common.CommandTrees.Internal; 
 
namespace System.Data.Common.CommandTrees
{ 
    /// 
    /// Represents an apply operation, which is the invocation of the specified functor for each element in the specified input set.
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbApplyExpression : DbExpression
    { 
        DbExpressionBinding m_input; 
        DbExpressionBinding m_apply;
 
        internal DbApplyExpression(DbCommandTree cmdTree,
            DbExpressionBinding input,
            DbExpressionBinding apply, DbExpressionKind applyKind)
            : base(cmdTree, applyKind) 
        {
            // 
            // Validate and initialize the input expression binding 
            //
            DbExpressionBinding.Check("Input", input, cmdTree); 
            m_input = input;

            //
            // Validate and initialize the apply expression binding 
            //
            DbExpressionBinding.Check("Apply", apply, cmdTree); 
            m_apply = apply; 

            // 
            // Duplicate Input and Apply binding names are not allowed
            //
            if (input.VariableName.Equals(apply.VariableName, StringComparison.Ordinal))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Apply_DuplicateVariableNames);
            } 
 
            //
            // Validate the DbExpressionKind is correct for DbApplyExpression 
            //
            Debug.Assert(DbExpressionKind.CrossApply == applyKind || DbExpressionKind.OuterApply == applyKind, "Invalid DbExpressionKind for DbApplyExpression");

            // 
            // Initialize the result type
            // 
            List> recordCols = new List>(); 
            recordCols.Add(new KeyValuePair(this.m_input.VariableName, this.m_input.VariableType));
            recordCols.Add(new KeyValuePair(this.m_apply.VariableName, this.m_apply.VariableType)); 

            this.ResultType = CommandTreeTypeHelper.CreateCollectionOfRowResultType(recordCols);
        }
 
        /// 
        /// Gets the  that specifies the functor that is invoked for each element in the input set. 
        ///  
        public DbExpressionBinding Apply
        { 
            get { return m_apply;  }
        }

        ///  
        /// Gets the  that specifies the input set.
        ///  
        public DbExpressionBinding Input { get { return m_input; } } 

        ///  
        /// The visitor pattern method for expression visitors that do not produce a result value.
        /// 
        /// An instance of DbExpressionVisitor.
        ///  is null 
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
 
        ///  
        /// The visitor pattern method for expression visitors that produce a result value of a specific type.
        ///  
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.
        /// The type of the result produced by 
        ///  is null
        /// An instance of . 
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
    } 
 
    /// 
    /// Represents the removal of duplicate elements from the specified set operand. 
    /// 
    /// 
    /// DbDistinctExpression requires that its argument has a collection result type
    /// with an element type that is equality comparable. 
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbDistinctExpression : DbUnaryExpression 
    {
        internal DbDistinctExpression(DbCommandTree cmdTree, DbExpression arg) 
            : base(cmdTree, DbExpressionKind.Distinct, arg)
        {
            //
            // Ensure that the Argument is of a collection type 
            //
            this.CheckCollectionArgument(); 
 
            //
            // Ensure that the Distinct operation is valid for the input 
            //
            CollectionType inputType = TypeHelpers.GetEdmType(arg.ResultType);
            if (!TypeHelpers.IsValidDistinctOpType(inputType.TypeUsage))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Distinct_InvalidCollection, "Argument");
            } 
 
            //
            // Result Type is the same collection type as the input 
            //
            this.ResultType = arg.ResultType;
        }
 
        /// 
        /// The visitor pattern method for expression visitors that do not produce a result value. 
        ///  
        /// An instance of DbExpressionVisitor.
        ///  is null 
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }

        /// 
        /// The visitor pattern method for expression visitors that produce a result value of a specific type. 
        /// 
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. 
        /// The type of the result produced by  
        ///  is null
        /// An instance of . 
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
    }

    ///  
    /// Represents the conversion of the specified set operand to a singleton.
    ///  
    ///  
    /// DbElementExpression requires that its argument has a collection result type
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbElementExpression : DbUnaryExpression
    {
        private bool _singlePropertyUnwrapped; 

        internal DbElementExpression(DbCommandTree cmdTree, DbExpression arg, bool unwrapSingleProperty) 
            : base(cmdTree, DbExpressionKind.Element, arg) 
        {
            // 
            // Ensure that the operand is actually of a collection type.
            //
            this.CheckCollectionArgument();
 
            _singlePropertyUnwrapped = unwrapSingleProperty;
 
            // 
            // Result Type is the element type of the collection type
            // 
            TypeUsage resultType = TypeHelpers.GetEdmType(arg.ResultType).TypeUsage;

            //
            // If needed, change the result type of the element expression to the type of the 
            // single property of the element of its operand
            // 
            if (unwrapSingleProperty) 
            {
                IList properties = TypeHelpers.GetProperties(resultType); 
                if (properties == null || properties.Count != 1)
                {
                    throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Element_InvalidArgumentForUnwrapSingleProperty, "arg");
                } 
                resultType = properties[0].TypeUsage;
            } 
 
            this.ResultType = resultType;
        } 

        /// 
        /// Is the result type of the element equal to the result type of the single property
        /// of the element of its operand? 
        /// 
        internal bool IsSinglePropertyUnwrapped { get { return _singlePropertyUnwrapped; } } 
 
        /// 
        /// The visitor pattern method for expression visitors that do not produce a result value. 
        /// 
        /// An instance of DbExpressionVisitor.
        ///  is null
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 

        ///  
        /// The visitor pattern method for expression visitors that produce a result value of a specific type. 
        /// 
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. 
        /// The type of the result produced by 
        ///  is null
        /// An instance of .
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 
    }
 
    ///  
    /// Represents the set subtraction operation between the left and right operands.
    ///  
    /// 
    /// DbExceptExpression requires that its arguments have a common collection result type
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbExceptExpression : DbBinaryExpression
    { 
        internal DbExceptExpression(DbCommandTree cmdTree, DbExpression left, DbExpression right) 
            : base(cmdTree, DbExpressionKind.Except, left, right)
        { 
            //
            // Ensure that the left and right operands are each of a collection type and that a common type exists for those types.
            //
            this.CheckCollectionArguments(); 

            // 
            // ensures arguments types are valid for EXCEPT 
            //
            this.CheckComparableSetArguments(); 

            //
            // Left Except Right produces a result with the same type as the Left operand
            // A Left operand with Type NullType is not allowed. 
            //
            if (TypeSemantics.IsNullType(this.Left.ResultType)) 
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Except_LeftNullTypeInvalid, "Left");
            } 

            this.ResultType = this.Left.ResultType;
        }
 
        /// 
        /// The visitor pattern method for expression visitors that do not produce a result value. 
        ///  
        /// An instance of DbExpressionVisitor.
        ///  is null 
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }

        /// 
        /// The visitor pattern method for expression visitors that produce a result value of a specific type. 
        /// 
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. 
        /// The type of the result produced by  
        ///  is null
        /// An instance of . 
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
    }

    ///  
    /// Represents a predicate applied to an input set to produce the set of elements that satisfy the predicate.
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbFilterExpression : DbExpression
    { 
        DbExpressionBinding _input;
        ExpressionLink _predicate;

        internal DbFilterExpression(DbCommandTree cmdTree, DbExpressionBinding input, DbExpression predExpr) 
            : base(cmdTree, DbExpressionKind.Filter)
        { 
            _predicate = new ExpressionLink("Predicate", cmdTree, PrimitiveTypeKind.Boolean, predExpr); 

            DbExpressionBinding.Check("Input", input, cmdTree); 
            _input = input;
            this.ResultType = _input.Expression.ResultType;
        }
 
        /// 
        /// Gets the  that specifies the input set. 
        ///  
        public DbExpressionBinding Input { get { return _input; } }
 
        /// 
        /// Gets or sets the  that specifies the predicate used to filter the input set.
        /// 
        /// The expression is null 
        /// 
        ///     The expression is not associated with the DbFilterExpression's command tree, 
        ///     or its result type is not a Boolean type. 
        /// 
        public DbExpression Predicate { get { return _predicate.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _predicate.Expression = value; } } 

        /// 
        /// The visitor pattern method for expression visitors that do not produce a result value.
        ///  
        /// An instance of DbExpressionVisitor.
        ///  is null 
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 

        ///  
        /// The visitor pattern method for expression visitors that produce a result value of a specific type.
        /// 
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.
        /// The type of the result produced by  
        ///  is null
        /// An instance of . 
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 
    }
 
    /// 
    /// Represents a group by operation, which is a grouping of the elements in the input set based on the specified key expressions followed by the application of the specified aggregates.
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbGroupByExpression : DbExpression
    { 
        private DbGroupExpressionBinding _input; 
        private IList _keys;
        private IList _aggregates; 

        internal DbGroupByExpression(DbCommandTree cmdTree,
                                    DbGroupExpressionBinding input,
                                    IList> groupKeys, 
                                    IList> aggregates)
            : base(cmdTree, DbExpressionKind.GroupBy) 
        { 
            List colNames = new List();
            List> columns = new List>(); 

            List keys = new List();
            List aggs = new List();
 
            //
            // Validate the input set 
            // 
            DbGroupExpressionBinding.Check("Input", input, cmdTree);
 
            //
            // Validate the grouping keys
            //
            CommandTreeUtils.CheckNamedList 
            (
                "groupKeys", 
                groupKeys, 
                true, // Allow empty list
                delegate(KeyValuePair keyInfo, int index) 
                {
                    //
                    // The result Type of an expression used as a group key must be equality comparable
                    // 
                    if (!TypeHelpers.IsValidGroupKeyType(keyInfo.Value.ResultType))
                    { 
                        throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_GroupBy_KeyNotEqualityComparable(keyInfo.Key)); 
                    }
 
                    keys.Add(keyInfo.Value);

                    //
                    // Track the cumulative set of column names 
                    //
                    colNames.Add(keyInfo.Key); 
 
                    columns.Add(new KeyValuePair(keyInfo.Key, keyInfo.Value.ResultType));
                } 
            );

            //
            // Validate the aggregates 
            //
            CommandTreeUtils.CheckNamedList 
            ( 
                "aggregates",
                aggregates, 
                true, // Allow empty list
                delegate(KeyValuePair aggInfo, int idx)
                {
                    if (aggInfo.Value.CommandTree != cmdTree) 
                    {
                        throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_GroupBy_AggregateTreeMismatch); 
                    } 

                    // 
                    // Is there a grouping key with the same name?
                    //
                    if (colNames.Contains(aggInfo.Key))
                    { 
                        throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_GroupBy_AggregateColumnExistsAsGroupColumn(aggInfo.Key));
                    } 
 
                    aggs.Add(aggInfo.Value);
                    columns.Add(new KeyValuePair(aggInfo.Key, aggInfo.Value.ResultType)); 
                }
            );

            // 
            // Either the Keys or Aggregates may be omitted, but not both
            // 
            if (0 == keys.Count && 0 == aggs.Count) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_GroupBy_AtLeastOneKeyOrAggregate); 
            }

            //
            // Initialize member variables. Group keys are read-write/fixed size, type-immutable, aggregates are read-only (but their arguments are read-write type-immutable) 
            //
            _input = input; 
            _keys = new ExpressionList("Keys", cmdTree, keys); 
            _aggregates = aggs.AsReadOnly();
 
            //
            // Create the result type. This is a collection of the record type produced by the group keys and aggregates.
            //
            this.ResultType = CommandTreeTypeHelper.CreateCollectionOfRowResultType(columns); 
        }
 
        ///  
        /// Gets the  that specifies the input set and provides access to the set element and group element variables.
        ///  
        public DbGroupExpressionBinding Input { get { return _input; } }

        /// 
        /// Gets an  list that provides grouping keys. 
        /// 
        public IList Keys { get { return _keys; } } 
 
        /// 
        /// Gets an  list that provides the aggregates to apply. 
        /// 
        public IList Aggregates { get { return _aggregates; } }

        ///  
        /// The visitor pattern method for expression visitors that do not produce a result value.
        ///  
        /// An instance of DbExpressionVisitor. 
        ///  is null
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 

        /// 
        /// The visitor pattern method for expression visitors that produce a result value of a specific type.
        ///  
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.
        /// The type of the result produced by  
        ///  is null 
        /// An instance of .
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 
    }

    /// 
    /// Represents the set intersection operation between the left and right operands. 
    /// 
    ///  
    /// DbIntersectExpression requires that its arguments have a common collection result type 
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbIntersectExpression : DbBinaryExpression
    {
        internal DbIntersectExpression(DbCommandTree cmdTree, DbExpression left, DbExpression right)
            : base(cmdTree, DbExpressionKind.Intersect, left, right) 
        {
            // 
            // Ensure that the left and right operands are each of a collection type and that a common type exists for those types. 
            //
            this.ResultType = this.CheckCollectionArguments(); 

            //
            // ensures arguments types are valid for INTERSECT
            // 
            this.CheckComparableSetArguments();
        } 
 
        /// 
        /// The visitor pattern method for expression visitors that do not produce a result value. 
        /// 
        /// An instance of DbExpressionVisitor.
        ///  is null
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 

        ///  
        /// The visitor pattern method for expression visitors that produce a result value of a specific type. 
        /// 
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. 
        /// The type of the result produced by 
        ///  is null
        /// An instance of .
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 
    }
 
    ///  
    /// Represents an unconditional join operation between the given collection arguments
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbCrossJoinExpression : DbExpression
    {
        private IList _inputs; 

        internal DbCrossJoinExpression(DbCommandTree cmdTree, IList inputs) 
            : base(cmdTree, DbExpressionKind.CrossJoin) 
       {
            // 
            // Ensure that the list of input expression bindings is non-null.
            //
            EntityUtil.CheckArgumentNull(inputs, "inputs");
 
            //
            // Validate the input expression bindings and build the column types for the record type 
            // component of the collection of record type result type of the join. 
            //
            List inputList = new List(inputs.Count); 
            List> columns = new List>(inputs.Count);
            Dictionary bindingNames = new Dictionary();
            for (int iPos = 0; iPos < inputs.Count; iPos++)
            { 
                DbExpressionBinding input = inputs[iPos];
 
                // 
                // Validate the DbExpressionBinding before accessing its properties
                // 
                DbExpressionBinding.Check(CommandTreeUtils.FormatIndex("Inputs", iPos), input, cmdTree);

                //
                // Duplicate binding names are not allowed 
                //
                int nameIndex = -1; 
                if(bindingNames.TryGetValue(input.VariableName, out nameIndex)) 
                {
                    throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_CrossJoin_DuplicateVariableNames(nameIndex, iPos, input.VariableName)); 
                }

                inputList.Add(input);
                bindingNames.Add(input.VariableName, iPos); 

                columns.Add(new KeyValuePair(input.VariableName, input.VariableType)); 
            } 

            if (inputList.Count < 2) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_CrossJoin_AtLeastTwoInputs, "inputs");
            }
 
            //
            // Initialize state 
            // 
            _inputs = inputList.AsReadOnly();
 
            //
            // Initialize the result type
            //
            this.ResultType = CommandTreeTypeHelper.CreateCollectionOfRowResultType(columns); 
       }
 
        ///  
        /// Gets an  list that provide the input sets to the join.
        ///  
        public IList Inputs { get { return _inputs; } }

        /// 
        /// The visitor pattern method for expression visitors that do not produce a result value. 
        /// 
        /// An instance of DbExpressionVisitor. 
        ///  is null 
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
 
        /// 
        /// The visitor pattern method for expression visitors that produce a result value of a specific type.
        /// 
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. 
        /// The type of the result produced by 
        ///  is null 
        /// An instance of . 
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
    } 

    /// 
    /// Represents an inner, left outer or full outer join operation between the given collection arguments on the specified join condition.
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbJoinExpression : DbExpression 
    { 
        private DbExpressionBinding _left;
        private DbExpressionBinding _right; 
        private ExpressionLink _cond;

        internal DbJoinExpression(DbCommandTree cmdTree, DbExpressionKind joinKind, DbExpressionBinding left, DbExpressionBinding right, DbExpression joinCond)
            : base(cmdTree, joinKind) 
        {
            Debug.Assert(DbExpressionKind.InnerJoin == joinKind || 
                         DbExpressionKind.LeftOuterJoin == joinKind || 
                         DbExpressionKind.FullOuterJoin == joinKind,
                         "Invalid DbExpressionKind specified for DbJoinExpression"); 

            //
            // Validate
            // 
            DbExpressionBinding.Check("Left", left, cmdTree);
            DbExpressionBinding.Check("Right", right, cmdTree); 
 
            //
            // Duplicate Left and Right binding names are not allowed 
            //
            if (left.VariableName.Equals(right.VariableName, StringComparison.Ordinal))
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Join_DuplicateVariableNames); 
            }
 
            // 
            // Initialize state (this also validates the JoinCondition)
            // 
            _left = left;
            _right = right;
            _cond = new ExpressionLink("JoinCondition", cmdTree, PrimitiveTypeKind.Boolean, joinCond);
 
            //
            // Initialize the result type 
            // 
            List> columns = new List>(2);
            columns.Add(new KeyValuePair(left.VariableName, left.VariableType)); 
            columns.Add(new KeyValuePair(right.VariableName, right.VariableType));

            this.ResultType = CommandTreeTypeHelper.CreateCollectionOfRowResultType(columns);
        } 

        ///  
        /// Gets the  provides the left input. 
        /// 
        public DbExpressionBinding Left { get { return _left; } } 

        /// 
        /// Gets the  provides the right input.
        ///  
        public DbExpressionBinding Right { get { return _right; } }
 
        ///  
        /// Gets or sets the optional join condition to apply.
        ///  
        /// The expression is null
        /// 
        ///     The expression is not associated with the DbJoinExpression's command tree,
        ///     or its result type is not a Boolean type. 
        /// 
        public DbExpression JoinCondition 
        { 
            get { return _cond.Expression; }
            /*CQT_PUBLIC_API(*/internal/*)*/ set 
            {
                _cond.Expression = value;
            }
        } 

        ///  
        /// The visitor pattern method for expression visitors that do not produce a result value. 
        /// 
        /// An instance of DbExpressionVisitor. 
        ///  is null
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }

        ///  
        /// The visitor pattern method for expression visitors that produce a result value of a specific type.
        ///  
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. 
        /// The type of the result produced by 
        ///  is null 
        /// An instance of .
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
    }
 
    /// 
    /// Represents the restriction of the number of elements in the Argument collection to the specified Limit value. 
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbLimitExpression : DbExpression 
    {
        private ExpressionLink _argument;
        private ExpressionLink _limit;
        private bool _withTies; 

        internal DbLimitExpression(DbCommandTree commandTree, DbExpression argument, DbExpression limit, bool withTies) 
            : base(commandTree, DbExpressionKind.Limit) 
        {
            // 
            // Initialize the Argument ExpressionLink. In addition to being non-null and from the same command tree,
            // the Argument expression must have a collection result type.
            //
            _argument = new ExpressionLink("Argument", commandTree, argument); 
            if (!TypeSemantics.IsCollectionType(argument.ResultType))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Unary_CollectionRequired(this.GetType().Name), "Argument"); 
            }
 
            //
            // Initialize the Limit ExpressionLink. In addition to being non-null and from the same command tree,
            // the Limit expression must also have an integer result type.
            // 
            _limit = new ExpressionLink("Limit", commandTree, limit);
            if (!TypeSemantics.IsIntegerNumericType(_limit.Expression.ResultType)) 
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Limit_IntegerRequired, "Limit");
            } 

            //
            // Currently the Limit expression is also required to be either a DbConstantExpression or a DbParameterReferenceExpression.
            // 
            if (limit.ExpressionKind != DbExpressionKind.Constant &&
                limit.ExpressionKind != DbExpressionKind.ParameterReference) 
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Limit_ConstantOrParameterRefRequired, "Limit");
            } 

            //
            // For constants, verify the limit is non-negative.
            // 
            if (CommandTreeTypeHelper.IsConstantNegativeInteger(limit))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Limit_NonNegativeLimitRequired, "Limit"); 
            }
 
            // Initalize the 'With Ties' property from the _withTies argument.
            _withTies = withTies;

            // 
            // Initialize the result type. The ResultType of DbLimitExpression is the same as the result type of its argument.
            // 
            this.ResultType = _argument.Expression.ResultType; 
        }
 
        /// 
        /// Gets or sets an expression that specifies the input collection.
        /// 
        /// The expression is null 
        /// 
        ///     The expression is not associated with the DbLimitExpression's command tree, 
        ///     or its result type is not a collection type. 
        /// 
        public DbExpression Argument 
        {
            get { return _argument.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _argument.Expression = value; }
        }
 
        /// 
        /// Gets or sets an expression that specifies the limit on the number of elements returned from the input collection. 
        ///  
        /// The expression is null
        ///  
        ///     The expression is not associated with the DbLimitExpression's command tree,
        ///     or is not one of  or ,
        ///     or its result type is not equal or promotable to a 64-bit integer type.
        ///  
        public DbExpression Limit
        { 
            get { return _limit.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _limit.Expression = value; } 
        }
 
        /// 
        /// Gets whether the limit operation will include tied results, which could produce more results than specifed by the Limit value if ties are present.
        /// 
        public bool WithTies { get { return _withTies; } } 

        ///  
        /// The visitor pattern method for expression visitors that do not produce a result value. 
        /// 
        /// An instance of DbExpressionVisitor. 
        ///  is null
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }

        ///  
        /// The visitor pattern method for expression visitors that produce a result value of a specific type.
        ///  
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. 
        /// The type of the result produced by 
        ///  is null 
        /// An instance of .
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
    }
 
    /// 
    /// Represents the projection of a given set of values over the specified input set. 
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbProjectExpression : DbExpression 
    {
        DbExpressionBinding _input;
        ExpressionLink _proj;
 
        internal DbProjectExpression(DbCommandTree cmdTree, DbExpressionBinding input, DbExpression projection)
            : base(cmdTree, DbExpressionKind.Project) 
        { 
            DbExpressionBinding.Check("Input", input, cmdTree);
            _input = input; 

            _proj = new ExpressionLink("Projection", cmdTree, projection);

            // 
            // Project produces a collection with an element type corresponding to the Type produced by the projection expression.
            // 
            this.ResultType = CommandTreeTypeHelper.CreateCollectionResultType(this.Projection.ResultType); 
        }
 
        /// 
        /// Gets the  that specifies the input set.
        /// 
        public DbExpressionBinding Input { get { return _input; } } 

        ///  
        /// Gets or sets the  that defines the projection. 
        /// 
        /// The expression is null 
        /// 
        ///     The expression is not associated with the DbProjectExpression's command tree,
        ///     or its result type is not equal or promotable to the result type of the current projection.
        ///  
        public DbExpression Projection { get { return _proj.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _proj.Expression = value; } }
 
        ///  
        /// The visitor pattern method for expression visitors that do not produce a result value.
        ///  
        /// An instance of DbExpressionVisitor.
        ///  is null
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
 
        /// 
        /// The visitor pattern method for expression visitors that produce a result value of a specific type. 
        ///  
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.
        /// The type of the result produced by  
        ///  is null
        /// An instance of .
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
    } 

    ///  
    /// Represents a quantifier operation of the specified kind (Any, All) over the elements of the specified input set. 
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbQuantifierExpression : DbExpression
    {
        DbExpressionBinding _input;
        ExpressionLink _pred; 

        internal DbQuantifierExpression(DbCommandTree cmdTree, DbExpressionKind kind, 
            DbExpressionBinding input, DbExpression pred) 
            : base(cmdTree, kind)
        { 
            DbExpressionBinding.Check("Input", input, cmdTree);
            _input = input;

            _pred = new ExpressionLink("Predicate", cmdTree, PrimitiveTypeKind.Boolean, pred); 

            this.ResultType = cmdTree.TypeHelper.CreateBooleanResultType(); 
        } 

        ///  
        /// Gets the  that specifies the input set.
        /// 
        public DbExpressionBinding Input { get { return _input; } }
 
        /// 
        /// Gets or sets the Boolean predicate that should be evaluated for each element in the input set. 
        ///  
        /// The expression is null
        ///  
        ///     The expression is not associated with the DbQuantifierExpression's command tree,
        ///     or its result type is not a Boolean type.
        /// 
        public DbExpression Predicate { get { return _pred.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _pred.Expression = value; } } 

        ///  
        /// The visitor pattern method for expression visitors that do not produce a result value. 
        /// 
        /// An instance of DbExpressionVisitor. 
        ///  is null
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }

        ///  
        /// The visitor pattern method for expression visitors that produce a result value of a specific type.
        ///  
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType. 
        /// The type of the result produced by 
        ///  is null 
        /// An instance of .
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
    }
 
    /// 
    /// Specifies a sort key that can be used as part of the sort order in a DbSortExpression. 
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbSortClause 
    {
        private ExpressionLink _expr;
        private bool _asc;
        private string _coll; 

        internal DbSortClause(DbExpression key, bool asc, string collation) 
        { 
            if (null == key)
            { 
                throw EntityUtil.ArgumentNull("key");
            }

            _expr = new ExpressionLink("Expression", key.CommandTree, key); 
            if (!TypeHelpers.IsValidSortOpKeyType(this.Expression.ResultType))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Sort_OrderComparable, "key"); 
            }
 
            if(!string.IsNullOrEmpty(collation) && !TypeSemantics.IsPrimitiveType(this.Expression.ResultType, PrimitiveTypeKind.String))
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Sort_NonStringCollationInvalid, "collation");
            } 

            _asc = asc; 
            _coll = collation; 
        }
 
        /// 
        /// Gets a Boolean value indicating whether or not this sort key is sorted ascending.
        /// 
        public bool Ascending { get { return _asc; } } 

        ///  
        /// Gets a string value that specifies the collation for this sort key. 
        /// 
        public string Collation { get { return _coll; } } 

        /// 
        /// Gets or sets the  that provides the value for this sort key.
        ///  
        /// The expression is null
        ///  
        ///     The expression is not associated with the DbSortClause's command tree, 
        ///     or its result type is not equal or promotable to the result type
        ///     of the current value of the property. 
        /// 
        public DbExpression Expression { get { return _expr.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _expr.Expression = value; } }
    }
 
    /// 
    /// Represents a skip operation of the specified number of elements of the input set after the ordering described in the given sort keys is applied. 
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbSkipExpression : DbExpression 
    {
        private DbExpressionBinding _input;
        private IList _keys;
        private ExpressionLink _count; 

        internal DbSkipExpression(DbCommandTree commandTree, DbExpressionBinding input, IList sortOrder, DbExpression count) 
            : base(commandTree, DbExpressionKind.Skip) 
        {
            // 
            // Perform common Sort argument validation
            //
            DbSortExpression.CheckSortArguments(commandTree, input, sortOrder);
            _input = input; 
            _keys = CommandTreeUtils.NewReadOnlyList(sortOrder);
 
            // 
            // Initialize the Count ExpressionLink. In addition to being non-null and from the same command tree,
            // the Count expression must also have an integer result type. 
            //
            _count = new ExpressionLink("Count", commandTree, count);
            if (!TypeSemantics.IsIntegerNumericType(_count.Expression.ResultType))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Skip_IntegerRequired, "Count");
            } 
 
            //
            // Currently the Count expression is also required to be either a DbConstantExpression or a DbParameterReferenceExpression. 
            //
            if (count.ExpressionKind != DbExpressionKind.Constant &&
                count.ExpressionKind != DbExpressionKind.ParameterReference)
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Skip_ConstantOrParameterRefRequired, "Count");
            } 
 
            //
            // For constants, verify the count is non-negative. 
            //
            if (CommandTreeTypeHelper.IsConstantNegativeInteger(count))
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Skip_NonNegativeCountRequired, "Count"); 
            }
 
            this.ResultType = _input.Expression.ResultType; 
        }
 
        /// 
        /// Gets the  that specifies the input set.
        /// 
        public DbExpressionBinding Input { get { return _input; } } 

        ///  
        /// Gets a  list that defines the sort order. 
        /// 
        public IList SortOrder { get { return _keys; } } 

        /// 
        /// Gets or sets an expression that specifies the number of elements from the input collection to skip.
        ///  
        /// The expression is null
        ///  
        ///     The expression is not associated with the DbSkipExpression's command tree, 
        ///     or is not one of  or ,
        ///     or its result type is not equal or promotable to a 64-bit integer type. 
        /// 
        public DbExpression Count
        {
            get { return _count.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _count.Expression = value; } 
        }
 
        ///  
        /// The visitor pattern method for expression visitors that do not produce a result value.
        ///  
        /// An instance of DbExpressionVisitor.
        ///  is null
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
 
        /// 
        /// The visitor pattern method for expression visitors that produce a result value of a specific type. 
        ///  
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.
        /// The type of the result produced by  
        ///  is null
        /// An instance of .
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
    } 

    ///  
    /// Represents a sort operation applied to the elements of the specified input set based on the given sort keys. 
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbSortExpression : DbExpression
    {
        private DbExpressionBinding _input;
        private IList _keys; 

        internal DbSortExpression(DbCommandTree cmdTree, DbExpressionBinding input, IList sortOrder) 
            : base(cmdTree,DbExpressionKind.Sort) 
        {
            DbSortExpression.CheckSortArguments(cmdTree, input, sortOrder); 

            _input = input;
            _keys = CommandTreeUtils.NewReadOnlyList(sortOrder);
 
            this.ResultType = input.Expression.ResultType;
        } 
 
        /// 
        /// Gets the  that specifies the input set. 
        /// 
        public DbExpressionBinding Input { get { return _input; } }

        ///  
        /// Gets a  list that defines the sort order.
        ///  
        public IList SortOrder { get { return _keys; } } 

        ///  
        /// The visitor pattern method for expression visitors that do not produce a result value.
        /// 
        /// An instance of DbExpressionVisitor.
        ///  is null 
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
 
        ///  
        /// The visitor pattern method for expression visitors that produce a result value of a specific type.
        ///  
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.
        /// The type of the result produced by 
        ///  is null
        /// An instance of . 
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } }
 
        ///  
        /// Validates the input and sort key arguments to both DbSkipExpression and DbSortExpression.
        ///  
        /// The Command Tree used to create the new Skip or Sort DbExpression
        /// A DbExpressionBinding that provides the collection to be ordered
        /// A list of SortClauses that specifies the sort order to apply to the input collection
        internal static void CheckSortArguments(DbCommandTree cmdTree, DbExpressionBinding input, IList keys) 
        {
            // 
            // Validate the Input 
            //
            DbExpressionBinding.Check("Input", input, cmdTree); 

            //
            // Validate the Sort keys
            // 
            EntityUtil.CheckArgumentNull(keys, "SortOrder");
            if (keys.Count < 1) 
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_SkipSort_AtLeastOneKey, "SortOrder");
            } 

            for (int idx = 0; idx < keys.Count; idx++)
            {
                DbSortClause key = keys[idx]; 

                if (null == key) 
                { 
                    throw EntityUtil.ArgumentNull(CommandTreeUtils.FormatIndex("SortOrder", idx));
                } 

                if (!object.ReferenceEquals(key.Expression.CommandTree, cmdTree))
                {
                    throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_General_TreeMismatch, CommandTreeUtils.FormatIndex("SortOrder", idx)); 
                }
            } 
        } 
    }
 
    /// 
    /// Represents the set union (without duplicate removal) operation between the left and right operands.
    /// 
    ///  
    /// DbUnionAllExpression requires that its arguments have a common collection result type
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbUnionAllExpression : DbBinaryExpression
    { 
        internal DbUnionAllExpression(DbCommandTree cmdTree, DbExpression left, DbExpression right)
            : base(cmdTree, DbExpressionKind.UnionAll, left, right)
        {
            // 
            // Ensure that the left and right operands are each of a collection type and that a common type exists for those types.
            // 
            this.ResultType = this.CheckCollectionArguments(); 
        }
 
        /// 
        /// The visitor pattern method for expression visitors that do not produce a result value.
        /// 
        /// An instance of DbExpressionVisitor. 
        ///  is null
        public override void Accept(DbExpressionVisitor visitor) { if (visitor != null) { visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 
 
        /// 
        /// The visitor pattern method for expression visitors that produce a result value of a specific type. 
        /// 
        /// An instance of a typed DbExpressionVisitor that produces a result value of type TResultType.
        /// The type of the result produced by 
        ///  is null 
        /// An instance of .
        public override TResultType Accept(DbExpressionVisitor visitor) { if (visitor != null) { return visitor.Visit(this); } else { throw EntityUtil.ArgumentNull("visitor"); } } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK