AbstractExpressions.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataEntity / System / Data / Common / CommandTrees / AbstractExpressions.cs / 2 / AbstractExpressions.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....], [....]
//--------------------------------------------------------------------- 
 
using System;
using System.Collections.Generic; 
using System.Data.Common;
using System.Diagnostics;
using System.Globalization;
using System.Data.Metadata.Edm; 
using System.Data.Common.CommandTrees.Internal;
 
namespace System.Data.Common.CommandTrees 
{
    ///  
    /// Describes the different "kinds" (classes) of expressions
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public enum DbExpressionKind 
    {
        ///  
        /// True for all. 
        /// 
        All, 

        /// 
        /// Logical And.
        ///  
        And,
 
        ///  
        /// True for any.
        ///  
        Any,

        /// 
        /// Conditional case statement. 
        /// 
        Case, 
 
        /// 
        /// Polymorphic type cast. 
        /// 
        Cast,

        ///  
        /// A constant value.
        ///  
        Constant, 

        ///  
        /// Cross apply
        /// 
        CrossApply,
 
        /// 
        /// Cross join 
        ///  
        CrossJoin,
 
        /// 
        /// Dereference.
        /// 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Deref")] 
        Deref,
 
        ///  
        /// Duplicate removal.
        ///  
        Distinct,

        /// 
        /// Division. 
        /// 
        Divide, 
 
        /// 
        /// Set to singleton conversion. 
        /// 
        Element,

        ///  
        /// Entity ref value retrieval.
        ///  
        EntityRef, 

        ///  
        /// Equality
        /// 
        Equals,
 
        /// 
        /// Set subtraction 
        ///  
        Except,
 
        /// 
        /// Restriction.
        /// 
        Filter, 

        ///  
        /// Full outer join 
        /// 
        FullOuterJoin, 

        /// 
        /// Invocation of a stand-alone function
        ///  
        Function,
 
        ///  
        /// Greater than.
        ///  
        GreaterThan,

        /// 
        /// Greater than or equal. 
        /// 
        GreaterThanOrEquals, 
 
        /// 
        /// Grouping. 
        /// 
        GroupBy,

        ///  
        /// Inner join
        ///  
        InnerJoin, 

        ///  
        /// Set intersection.
        /// 
        Intersect,
 
        /// 
        /// Empty set determination. 
        ///  
        IsEmpty,
 
        /// 
        /// Null determination.
        /// 
        IsNull, 

        ///  
        /// Type comparison (specified Type or Subtype). 
        /// 
        IsOf, 

        /// 
        /// Type comparison (specified Type only).
        ///  
        IsOfOnly,
 
        ///  
        /// Left outer join
        ///  
        LeftOuterJoin,

        /// 
        /// Less than. 
        /// 
        LessThan, 
 
        /// 
        /// Less than or equal. 
        /// 
        LessThanOrEquals,

        ///  
        /// String comparison.
        ///  
        Like, 

        ///  
        /// Result count restriction (TOP n).
        /// 
        Limit,
 
#if METHOD_EXPRESSION
        ///  
        /// Invocation of a static or instance method. 
        /// 
        Method, 
#endif

        /// 
        /// Subtraction. 
        /// 
        Minus, 
 
        /// 
        /// Modulo. 
        /// 
        Modulo,

        ///  
        /// Multiplication.
        ///  
        Multiply, 

        ///  
        /// Instance, row, and set construction.
        /// 
        NewInstance,
 
        /// 
        /// Logical Not. 
        ///  
        Not,
 
        /// 
        /// Inequality.
        /// 
        NotEquals, 

        ///  
        /// Null. 
        /// 
        Null, 

        /// 
        /// Set members by type (or subtype).
        ///  
        OfType,
 
        ///  
        /// Set members by (exact) type.
        ///  
        OfTypeOnly,

        /// 
        /// Logical Or. 
        /// 
        Or, 
 
        /// 
        /// Outer apply. 
        /// 
        OuterApply,

        ///  
        /// A reference to a parameter.
        ///  
        ParameterReference, 

        ///  
        /// Addition.
        /// 
        Plus,
 
        /// 
        /// Projection. 
        ///  
        Project,
 
        /// 
        /// Retrieval of a static or instance property.
        /// 
        Property, 

        ///  
        /// Reference. 
        /// 
        Ref, 

        /// 
        /// Ref key value retrieval.
        ///  
        RefKey,
 
        ///  
        /// Navigation of a (composition or association) relationship.
        ///  
        RelationshipNavigation,

        /// 
        /// Entity or relationship set scan. 
        /// 
        Scan, 
 
        /// 
        /// Skip elements of an ordered collection. 
        /// 
        Skip,

        ///  
        /// Sorting.
        ///  
        Sort, 

        ///  
        /// Type conversion.
        /// 
        Treat,
 
        /// 
        /// Negation. 
        ///  
        UnaryMinus,
 
        /// 
        /// Set union (with duplicates).
        /// 
        UnionAll, 

        ///  
        /// A reference to a variable. 
        /// 
        VariableReference 
    }

    /// 
    /// The base type for all expressions 
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public abstract class DbExpression 
    {
        TypeUsage _type; 
        DbExpressionKind _kind;
        DbCommandTree _commandTree;

        private static int s_instanceCount; // Bid counter 
        internal readonly int ObjectId = System.Threading.Interlocked.Increment(ref s_instanceCount);
 
        internal DbExpression(DbCommandTree commandTree, DbExpressionKind kind) 
        {
            CheckExpressionKind(kind); 
            _commandTree = EntityUtil.CheckArgumentNull(commandTree, "commandTree");
            _kind = kind;
        }
 
        /// 
        /// Gets the type metadata for the result type of the expression. 
        ///  
        public TypeUsage ResultType
        { 
            get
            {
#if DEBUG
                if (_type == null) 
                {
                    Debug.Assert(false, string.Format(CultureInfo.InvariantCulture, "{0}.Type was not set by constructor", this.GetType().Name)); 
                } 
#endif
                return _type; 
            }

            internal set
            { 
                TypeUsage newValue = CommandTreeTypeHelper.SetResultAsNullable(value);
                Debug.Assert(newValue != null, "Null type metadata specified for DbExpression.Type"); 
                Debug.Assert(newValue.IsReadOnly, "Editable type metadata specified for DbExpression.Type"); 
                _type = newValue;
            } 
        }

        /// 
        /// Gets the kind of the expression, which indicates the operation of this expression. 
        /// 
        public DbExpressionKind ExpressionKind { get { return _kind; } } 
 
        /// 
        /// Gets the command tree with which this expression is associated. 
        /// 
        internal DbCommandTree CommandTree { get { return _commandTree; } }

        ///  
        /// The visitor pattern interface method for expression visitors that do not produce a result value.
        ///  
        /// An instance of DbExpressionVisitor. 
        ///  is null
        public abstract void Accept(DbExpressionVisitor visitor); 

        /// 
        /// The visitor pattern interface 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 abstract TResultType Accept(DbExpressionVisitor visitor); 

        /// 
        /// Creates a new DbExpression instance that is a copy of this expression. The new expression is owned by the same command tree.
        ///  
        /// The new DbExpression instance
        /*CQT_PUBLIC_API(*/internal/*)*/ DbExpression Clone() 
        { 
            using(new EntityBid.ScopeAuto(" %d#", this.ObjectId))
            { 
                return ExpressionCopier.Copy(this.CommandTree, this);
            }
        }
 
        #region Internal API
 
        ///  
        /// Produces a text-based tree representation of the DbExpression tree rooted at this expression
        ///  
        /// A string containing the text-based tree representation
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal string Print()
        { 
            return new ExpressionPrinter().Print(this);
        } 
 
        internal static int GetObjectId(DbExpression expression)
        { 
            return (null == expression ? -1 : expression.ObjectId);
        }

        internal static int GetExpressionKind(DbExpression expression) 
        {
            return (null == expression ? -1 : (int)expression.ExpressionKind); 
        } 

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static void TraceInfo(DbExpression expression)
        {
            if (expression != null && EntityBid.AdvancedOn)
            { 
                EntityBid.PutStr(expression.Print());
                EntityBid.Trace("\n"); 
            } 
        }
 
        internal static void CheckExpressionKind(DbExpressionKind kind)
        {
            // Add new valid DbExpressionKind values to this method as well as the enum itself.
            // DbExpressionKind is a contiguous enum from All = 0 through View 
            if ((kind < DbExpressionKind.All) || (DbExpressionKind.VariableReference < kind))
            { 
                throw EntityUtil.InvalidEnumerationValue(typeof(DbExpressionKind), (int)kind); 
            }
        } 
        #endregion
    }

    ///  
    /// The abstract base type for expressions that accept two expression operands.
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public abstract class DbBinaryExpression : DbExpression
    { 
        private ExpressionLink _left;
        private ExpressionLink _right;

        internal DbBinaryExpression(DbCommandTree commandTree, DbExpressionKind kind) 
            : base(commandTree, kind)
        { 
            _left = new ExpressionLink("Left", commandTree); 
            _right = new ExpressionLink("Right", commandTree);
        } 

        internal DbBinaryExpression(DbCommandTree commandTree, DbExpressionKind kind, DbExpression left, DbExpression right)
            : base(commandTree, kind)
        { 
            _left = new ExpressionLink("Left", commandTree, left);
            _right = new ExpressionLink("Right", commandTree, right); 
        } 

        ///  
        /// Gets or sets the  that defines the left argument.
        /// 
        /// The expression is null
        ///  
        ///     The expression is not associated with the DbBinaryExpression's command tree,
        ///     or its result type is not equal or promotable to the required 
        ///     type for the left argument. 
        /// 
        ///  
        ///     Derived expression types may perform stricter type checks when the
        ///     Left property is set, for example 
        ///     requires that its left expression has a collection result type, while 
        ///     requires a Boolean result type. 
        ///     Typically, derived expression types will not allow Left
        ///     to be set to an expression with a result type that is not equal or promotable 
        ///     to the result type of the current value. 
        /// 
        public DbExpression Left 
        {
            get { return _left.Expression; }
            /*CQT_PUBLIC_API(*/internal/*)*/ set { _left.Expression = value; }
        } 

        ///  
        /// Gets or sets the  that defines the right argument. 
        /// 
        /// The expression is null 
        /// 
        ///     The expression is not associated with the DbBinaryExpression's command tree,
        ///     or its result type is not equal or promotable to the required
        ///     type for the right argument. 
        /// 
        ///  
        ///     Derived expression types may perform stricter type checks when the 
        ///     Right property is set, for example 
        ///     requires that its right expression has a collection result type, while  
        ///     requires a Boolean result type.
        ///     Typically, derived expression types will not allow Right
        ///     to be set to an expression with a result type that is not equal or promotable
        ///     to the result type of the current value. 
        /// 
        public DbExpression Right 
        { 
            get { return _right.Expression; }
            /*CQT_PUBLIC_API(*/internal/*)*/ set { _right.Expression = value; } 
        }

        internal ExpressionLink LeftLink { get { return _left; } }
        internal ExpressionLink RightLink { get { return _right; } } 

        ///  
        /// Verifies that both Left and Right have a collection result type with a common element type, 
        /// and returns a new collection result type based on that common element type.
        ///  
        /// A new collection type based on the common element type of the collection result types of the Left and Right arguments
        /// If Left or Right does not have a collection result type or have collection types for which no common element type exists
        internal TypeUsage CheckCollectionArguments()
        { 
            Debug.Assert(this.Left != null && this.Right != null, string.Format(CultureInfo.InvariantCulture, "CheckCollectionArguments called on uninitialized {0}", this.GetType().Name));
 
            if (!TypeSemantics.IsCollectionType(this.Left.ResultType) || !TypeSemantics.IsCollectionType(this.Right.ResultType)) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Binary_CollectionsRequired(this.GetType().Name)); 
            }

            TypeUsage commonType = TypeHelpers.GetCommonTypeUsage(this.Left.ResultType, this.Right.ResultType);
            if (null == commonType) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Binary_CollectionsRequired(this.GetType().Name)); 
            } 

            return commonType; 
        }

        /// 
        /// Validates if left and right types are valid for set operation 
        /// 
        internal void CheckComparableSetArguments() 
        { 
            if (!TypeHelpers.IsSetComparableOpType(TypeHelpers.GetElementTypeUsage(this.Left.ResultType)))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_InvalidTypeForSetOperation(TypeHelpers.GetElementTypeUsage(this.Left.ResultType).Identity, this.GetType().Name), this._left.Name);
            }

            if (!TypeHelpers.IsSetComparableOpType(TypeHelpers.GetElementTypeUsage(this.Right.ResultType))) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_InvalidTypeForSetOperation(TypeHelpers.GetElementTypeUsage(this.Right.ResultType).Identity, this.GetType().Name), this._right.Name); 
            } 
        }
 
    }

    /// 
    /// The abstract base type for expressions that accept a single expression operand 
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public abstract class DbUnaryExpression : DbExpression 
    {
        private ExpressionLink _argLink; 

        internal DbUnaryExpression(DbCommandTree commandTree, DbExpressionKind kind)
            : base(commandTree, kind)
        { 
            _argLink = new ExpressionLink("Argument", commandTree);
        } 
 
        internal DbUnaryExpression(DbCommandTree commandTree, DbExpressionKind kind, DbExpression arg)
            : base(commandTree, kind) 
        {
            _argLink = new ExpressionLink("Argument", commandTree, arg);
        }
 
        /// 
        /// Gets or sets the  that defines the argument. 
        ///  
        /// The expression is null
        ///  
        ///     The expression is not associated with the DbUnaryExpression's command tree,
        ///     or its result type is not equal or promotable to the required
        ///     type for the argument.
        ///  
        /// 
        ///     Derived expression types may perform stricter type checks when the 
        ///     Argument property is set, for example  
        ///     requires that its argument expression has a collection result type.
        ///     Typically, derived expression types will not allow Argument 
        ///     to be set to an expression with a result type that is not equal or promotable
        ///     to the result type of the current value.
        /// 
        public DbExpression Argument 
        {
            get { return _argLink.Expression; } 
            /*CQT_PUBLIC_API(*/internal/*)*/ set { _argLink.Expression = value; } 
        }
 
        internal ExpressionLink ArgumentLink { get { return _argLink; } }

        internal void CheckCollectionArgument()
        { 
            Debug.Assert(this.Argument != null, string.Format(CultureInfo.InvariantCulture, "CheckCollectionArgument called on uninitialized {0}", this.GetType().Name));
 
            if (!TypeSemantics.IsCollectionType(this.Argument.ResultType)) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Unary_CollectionRequired(this.GetType().Name)); 
            }
        }
    }
} 

// 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.Data.Common;
using System.Diagnostics;
using System.Globalization;
using System.Data.Metadata.Edm; 
using System.Data.Common.CommandTrees.Internal;
 
namespace System.Data.Common.CommandTrees 
{
    ///  
    /// Describes the different "kinds" (classes) of expressions
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public enum DbExpressionKind 
    {
        ///  
        /// True for all. 
        /// 
        All, 

        /// 
        /// Logical And.
        ///  
        And,
 
        ///  
        /// True for any.
        ///  
        Any,

        /// 
        /// Conditional case statement. 
        /// 
        Case, 
 
        /// 
        /// Polymorphic type cast. 
        /// 
        Cast,

        ///  
        /// A constant value.
        ///  
        Constant, 

        ///  
        /// Cross apply
        /// 
        CrossApply,
 
        /// 
        /// Cross join 
        ///  
        CrossJoin,
 
        /// 
        /// Dereference.
        /// 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Deref")] 
        Deref,
 
        ///  
        /// Duplicate removal.
        ///  
        Distinct,

        /// 
        /// Division. 
        /// 
        Divide, 
 
        /// 
        /// Set to singleton conversion. 
        /// 
        Element,

        ///  
        /// Entity ref value retrieval.
        ///  
        EntityRef, 

        ///  
        /// Equality
        /// 
        Equals,
 
        /// 
        /// Set subtraction 
        ///  
        Except,
 
        /// 
        /// Restriction.
        /// 
        Filter, 

        ///  
        /// Full outer join 
        /// 
        FullOuterJoin, 

        /// 
        /// Invocation of a stand-alone function
        ///  
        Function,
 
        ///  
        /// Greater than.
        ///  
        GreaterThan,

        /// 
        /// Greater than or equal. 
        /// 
        GreaterThanOrEquals, 
 
        /// 
        /// Grouping. 
        /// 
        GroupBy,

        ///  
        /// Inner join
        ///  
        InnerJoin, 

        ///  
        /// Set intersection.
        /// 
        Intersect,
 
        /// 
        /// Empty set determination. 
        ///  
        IsEmpty,
 
        /// 
        /// Null determination.
        /// 
        IsNull, 

        ///  
        /// Type comparison (specified Type or Subtype). 
        /// 
        IsOf, 

        /// 
        /// Type comparison (specified Type only).
        ///  
        IsOfOnly,
 
        ///  
        /// Left outer join
        ///  
        LeftOuterJoin,

        /// 
        /// Less than. 
        /// 
        LessThan, 
 
        /// 
        /// Less than or equal. 
        /// 
        LessThanOrEquals,

        ///  
        /// String comparison.
        ///  
        Like, 

        ///  
        /// Result count restriction (TOP n).
        /// 
        Limit,
 
#if METHOD_EXPRESSION
        ///  
        /// Invocation of a static or instance method. 
        /// 
        Method, 
#endif

        /// 
        /// Subtraction. 
        /// 
        Minus, 
 
        /// 
        /// Modulo. 
        /// 
        Modulo,

        ///  
        /// Multiplication.
        ///  
        Multiply, 

        ///  
        /// Instance, row, and set construction.
        /// 
        NewInstance,
 
        /// 
        /// Logical Not. 
        ///  
        Not,
 
        /// 
        /// Inequality.
        /// 
        NotEquals, 

        ///  
        /// Null. 
        /// 
        Null, 

        /// 
        /// Set members by type (or subtype).
        ///  
        OfType,
 
        ///  
        /// Set members by (exact) type.
        ///  
        OfTypeOnly,

        /// 
        /// Logical Or. 
        /// 
        Or, 
 
        /// 
        /// Outer apply. 
        /// 
        OuterApply,

        ///  
        /// A reference to a parameter.
        ///  
        ParameterReference, 

        ///  
        /// Addition.
        /// 
        Plus,
 
        /// 
        /// Projection. 
        ///  
        Project,
 
        /// 
        /// Retrieval of a static or instance property.
        /// 
        Property, 

        ///  
        /// Reference. 
        /// 
        Ref, 

        /// 
        /// Ref key value retrieval.
        ///  
        RefKey,
 
        ///  
        /// Navigation of a (composition or association) relationship.
        ///  
        RelationshipNavigation,

        /// 
        /// Entity or relationship set scan. 
        /// 
        Scan, 
 
        /// 
        /// Skip elements of an ordered collection. 
        /// 
        Skip,

        ///  
        /// Sorting.
        ///  
        Sort, 

        ///  
        /// Type conversion.
        /// 
        Treat,
 
        /// 
        /// Negation. 
        ///  
        UnaryMinus,
 
        /// 
        /// Set union (with duplicates).
        /// 
        UnionAll, 

        ///  
        /// A reference to a variable. 
        /// 
        VariableReference 
    }

    /// 
    /// The base type for all expressions 
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public abstract class DbExpression 
    {
        TypeUsage _type; 
        DbExpressionKind _kind;
        DbCommandTree _commandTree;

        private static int s_instanceCount; // Bid counter 
        internal readonly int ObjectId = System.Threading.Interlocked.Increment(ref s_instanceCount);
 
        internal DbExpression(DbCommandTree commandTree, DbExpressionKind kind) 
        {
            CheckExpressionKind(kind); 
            _commandTree = EntityUtil.CheckArgumentNull(commandTree, "commandTree");
            _kind = kind;
        }
 
        /// 
        /// Gets the type metadata for the result type of the expression. 
        ///  
        public TypeUsage ResultType
        { 
            get
            {
#if DEBUG
                if (_type == null) 
                {
                    Debug.Assert(false, string.Format(CultureInfo.InvariantCulture, "{0}.Type was not set by constructor", this.GetType().Name)); 
                } 
#endif
                return _type; 
            }

            internal set
            { 
                TypeUsage newValue = CommandTreeTypeHelper.SetResultAsNullable(value);
                Debug.Assert(newValue != null, "Null type metadata specified for DbExpression.Type"); 
                Debug.Assert(newValue.IsReadOnly, "Editable type metadata specified for DbExpression.Type"); 
                _type = newValue;
            } 
        }

        /// 
        /// Gets the kind of the expression, which indicates the operation of this expression. 
        /// 
        public DbExpressionKind ExpressionKind { get { return _kind; } } 
 
        /// 
        /// Gets the command tree with which this expression is associated. 
        /// 
        internal DbCommandTree CommandTree { get { return _commandTree; } }

        ///  
        /// The visitor pattern interface method for expression visitors that do not produce a result value.
        ///  
        /// An instance of DbExpressionVisitor. 
        ///  is null
        public abstract void Accept(DbExpressionVisitor visitor); 

        /// 
        /// The visitor pattern interface 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 abstract TResultType Accept(DbExpressionVisitor visitor); 

        /// 
        /// Creates a new DbExpression instance that is a copy of this expression. The new expression is owned by the same command tree.
        ///  
        /// The new DbExpression instance
        /*CQT_PUBLIC_API(*/internal/*)*/ DbExpression Clone() 
        { 
            using(new EntityBid.ScopeAuto(" %d#", this.ObjectId))
            { 
                return ExpressionCopier.Copy(this.CommandTree, this);
            }
        }
 
        #region Internal API
 
        ///  
        /// Produces a text-based tree representation of the DbExpression tree rooted at this expression
        ///  
        /// A string containing the text-based tree representation
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal string Print()
        { 
            return new ExpressionPrinter().Print(this);
        } 
 
        internal static int GetObjectId(DbExpression expression)
        { 
            return (null == expression ? -1 : expression.ObjectId);
        }

        internal static int GetExpressionKind(DbExpression expression) 
        {
            return (null == expression ? -1 : (int)expression.ExpressionKind); 
        } 

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static void TraceInfo(DbExpression expression)
        {
            if (expression != null && EntityBid.AdvancedOn)
            { 
                EntityBid.PutStr(expression.Print());
                EntityBid.Trace("\n"); 
            } 
        }
 
        internal static void CheckExpressionKind(DbExpressionKind kind)
        {
            // Add new valid DbExpressionKind values to this method as well as the enum itself.
            // DbExpressionKind is a contiguous enum from All = 0 through View 
            if ((kind < DbExpressionKind.All) || (DbExpressionKind.VariableReference < kind))
            { 
                throw EntityUtil.InvalidEnumerationValue(typeof(DbExpressionKind), (int)kind); 
            }
        } 
        #endregion
    }

    ///  
    /// The abstract base type for expressions that accept two expression operands.
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public abstract class DbBinaryExpression : DbExpression
    { 
        private ExpressionLink _left;
        private ExpressionLink _right;

        internal DbBinaryExpression(DbCommandTree commandTree, DbExpressionKind kind) 
            : base(commandTree, kind)
        { 
            _left = new ExpressionLink("Left", commandTree); 
            _right = new ExpressionLink("Right", commandTree);
        } 

        internal DbBinaryExpression(DbCommandTree commandTree, DbExpressionKind kind, DbExpression left, DbExpression right)
            : base(commandTree, kind)
        { 
            _left = new ExpressionLink("Left", commandTree, left);
            _right = new ExpressionLink("Right", commandTree, right); 
        } 

        ///  
        /// Gets or sets the  that defines the left argument.
        /// 
        /// The expression is null
        ///  
        ///     The expression is not associated with the DbBinaryExpression's command tree,
        ///     or its result type is not equal or promotable to the required 
        ///     type for the left argument. 
        /// 
        ///  
        ///     Derived expression types may perform stricter type checks when the
        ///     Left property is set, for example 
        ///     requires that its left expression has a collection result type, while 
        ///     requires a Boolean result type. 
        ///     Typically, derived expression types will not allow Left
        ///     to be set to an expression with a result type that is not equal or promotable 
        ///     to the result type of the current value. 
        /// 
        public DbExpression Left 
        {
            get { return _left.Expression; }
            /*CQT_PUBLIC_API(*/internal/*)*/ set { _left.Expression = value; }
        } 

        ///  
        /// Gets or sets the  that defines the right argument. 
        /// 
        /// The expression is null 
        /// 
        ///     The expression is not associated with the DbBinaryExpression's command tree,
        ///     or its result type is not equal or promotable to the required
        ///     type for the right argument. 
        /// 
        ///  
        ///     Derived expression types may perform stricter type checks when the 
        ///     Right property is set, for example 
        ///     requires that its right expression has a collection result type, while  
        ///     requires a Boolean result type.
        ///     Typically, derived expression types will not allow Right
        ///     to be set to an expression with a result type that is not equal or promotable
        ///     to the result type of the current value. 
        /// 
        public DbExpression Right 
        { 
            get { return _right.Expression; }
            /*CQT_PUBLIC_API(*/internal/*)*/ set { _right.Expression = value; } 
        }

        internal ExpressionLink LeftLink { get { return _left; } }
        internal ExpressionLink RightLink { get { return _right; } } 

        ///  
        /// Verifies that both Left and Right have a collection result type with a common element type, 
        /// and returns a new collection result type based on that common element type.
        ///  
        /// A new collection type based on the common element type of the collection result types of the Left and Right arguments
        /// If Left or Right does not have a collection result type or have collection types for which no common element type exists
        internal TypeUsage CheckCollectionArguments()
        { 
            Debug.Assert(this.Left != null && this.Right != null, string.Format(CultureInfo.InvariantCulture, "CheckCollectionArguments called on uninitialized {0}", this.GetType().Name));
 
            if (!TypeSemantics.IsCollectionType(this.Left.ResultType) || !TypeSemantics.IsCollectionType(this.Right.ResultType)) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Binary_CollectionsRequired(this.GetType().Name)); 
            }

            TypeUsage commonType = TypeHelpers.GetCommonTypeUsage(this.Left.ResultType, this.Right.ResultType);
            if (null == commonType) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Binary_CollectionsRequired(this.GetType().Name)); 
            } 

            return commonType; 
        }

        /// 
        /// Validates if left and right types are valid for set operation 
        /// 
        internal void CheckComparableSetArguments() 
        { 
            if (!TypeHelpers.IsSetComparableOpType(TypeHelpers.GetElementTypeUsage(this.Left.ResultType)))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_InvalidTypeForSetOperation(TypeHelpers.GetElementTypeUsage(this.Left.ResultType).Identity, this.GetType().Name), this._left.Name);
            }

            if (!TypeHelpers.IsSetComparableOpType(TypeHelpers.GetElementTypeUsage(this.Right.ResultType))) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_InvalidTypeForSetOperation(TypeHelpers.GetElementTypeUsage(this.Right.ResultType).Identity, this.GetType().Name), this._right.Name); 
            } 
        }
 
    }

    /// 
    /// The abstract base type for expressions that accept a single expression operand 
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public abstract class DbUnaryExpression : DbExpression 
    {
        private ExpressionLink _argLink; 

        internal DbUnaryExpression(DbCommandTree commandTree, DbExpressionKind kind)
            : base(commandTree, kind)
        { 
            _argLink = new ExpressionLink("Argument", commandTree);
        } 
 
        internal DbUnaryExpression(DbCommandTree commandTree, DbExpressionKind kind, DbExpression arg)
            : base(commandTree, kind) 
        {
            _argLink = new ExpressionLink("Argument", commandTree, arg);
        }
 
        /// 
        /// Gets or sets the  that defines the argument. 
        ///  
        /// The expression is null
        ///  
        ///     The expression is not associated with the DbUnaryExpression's command tree,
        ///     or its result type is not equal or promotable to the required
        ///     type for the argument.
        ///  
        /// 
        ///     Derived expression types may perform stricter type checks when the 
        ///     Argument property is set, for example  
        ///     requires that its argument expression has a collection result type.
        ///     Typically, derived expression types will not allow Argument 
        ///     to be set to an expression with a result type that is not equal or promotable
        ///     to the result type of the current value.
        /// 
        public DbExpression Argument 
        {
            get { return _argLink.Expression; } 
            /*CQT_PUBLIC_API(*/internal/*)*/ set { _argLink.Expression = value; } 
        }
 
        internal ExpressionLink ArgumentLink { get { return _argLink; } }

        internal void CheckCollectionArgument()
        { 
            Debug.Assert(this.Argument != null, string.Format(CultureInfo.InvariantCulture, "CheckCollectionArgument called on uninitialized {0}", this.GetType().Name));
 
            if (!TypeSemantics.IsCollectionType(this.Argument.ResultType)) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Unary_CollectionRequired(this.GetType().Name)); 
            }
        }
    }
} 

// 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