ValueExpressions.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 / ValueExpressions.cs / 2 / ValueExpressions.cs

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

using System.Data.Common; 
using System.Data.Metadata.Edm;
using System.Data.Common.CommandTrees.Internal; 
 
namespace System.Data.Common.CommandTrees
{ 
    /// 
    /// Represents a constant value.
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbConstantExpression : DbExpression
    { 
        private object _value; 

        internal DbConstantExpression(DbCommandTree commandTree, object value) 
            : base(commandTree, DbExpressionKind.Constant)
        {
            if (null == value)
            { 
                throw EntityUtil.ArgumentNull("value");
            } 
 
            //
            // Check that typeof(value) is actually a valid constant (i.e. primitive) type 
            //
            PrimitiveTypeKind primitiveTypeKind;
            if (!CommandTreeUtils.TryGetPrimtiveTypeKind(value.GetType(), out primitiveTypeKind))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Constant_InvalidType, "value");
            } 
 
            TypeUsage typeMeta = TypeHelpers.GetLiteralTypeUsage(primitiveTypeKind);
 
            //
            // Set the value
            //
            _value = value; 
            this.ResultType = typeMeta;
        } 
 
        internal DbConstantExpression(DbCommandTree commandTree, object value, TypeUsage constantType)
            : base(commandTree, DbExpressionKind.Constant) 
        {
            //
            // Basic validation of constant value and constant type (non-null, read-only, etc)
            // 
            EntityUtil.CheckArgumentNull(value, "value");
            commandTree.TypeHelper.CheckType(constantType, "constantType"); 
 
            //
            // Verify that constantType is a primitive type and that value is an instance of that primitive type 
            // Note that the value is not validated against applicable facets (such as MaxLength for a string value),
            // this is left to the server.
            //
            PrimitiveType primitiveType; 
            if (!TypeHelpers.TryGetEdmType(constantType, out primitiveType))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Constant_InvalidConstantType(constantType.ToString()), "constantType"); 
            }
 
            PrimitiveTypeKind valueKind;
            if (!CommandTreeUtils.TryGetPrimtiveTypeKind(value.GetType(), out valueKind) ||
                primitiveType.PrimitiveTypeKind != valueKind)
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Constant_InvalidValueForType(constantType.ToString()), "value");
            } 
 
            //
            // Set the value 
            //
            _value = value;
            this.ResultType = constantType;
        } 

        ///  
        /// Gets the constant value. 
        /// 
        public object Value { get { return _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 null.
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbNullExpression : DbExpression
    { 
        internal DbNullExpression(DbCommandTree commandTree, TypeUsage type) 
            : base(commandTree, DbExpressionKind.Null)
        { 
            commandTree.TypeHelper.CheckType(type);
            this.ResultType = type;
        }
 
        /// 
        /// 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 reference to a variable that is currently in scope.
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbVariableReferenceExpression : DbExpression
    { 
        private string _name;

        internal DbVariableReferenceExpression(DbCommandTree cmdTree, TypeUsage type, string name)
            : base(cmdTree, DbExpressionKind.VariableReference) 
        {
            if (string.IsNullOrEmpty(name)) 
            { 
                throw EntityUtil.ArgumentNull("name");
            } 

            //
            // Verify the type of the reference. NullType is not allowed in Var or Parameter references.
            // 
            cmdTree.TypeHelper.CheckType(type);
 
            _name = name; 
            this.ResultType = type;
        } 

        /// 
        /// Gets the name of the referenced variable.
        ///  
        public string VariableName { get { return _name; } }
 
        ///  
        /// 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 reference to a parameter declared on the command tree that contains this expression. 
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbParameterReferenceExpression : DbExpression
    {
        private string _name;
 
        internal DbParameterReferenceExpression(DbCommandTree cmdTree, TypeUsage type, string name)
            : base(cmdTree, DbExpressionKind.ParameterReference) 
        { 
            EntityUtil.CheckArgumentNull(name, "name");
 
            // DbCommandTree.CreateParameterRefExpression should check that a parameter with the given name exists,
            // and DbCommandTree.AddParameter should have already verified that the name is valid, so this need only
            // be asserted here.
            Debug.Assert(DbCommandTree.IsValidParameterName(name), string.Format(CultureInfo.InvariantCulture, "Invalid parameter name passed to DbParameterReferenceExpression constructor: '{0}'", name)); 

            // 
            // Verify the type of the reference. NullType is not allowed in Var or Parameter references. 
            //
            cmdTree.TypeHelper.CheckType(type); 

            _name = name;
            this.ResultType = type;
        } 

        ///  
        /// Gets the name of the referenced parameter. 
        /// 
        public string ParameterName { get { return _name; } } 

        /// 
        /// 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 retrieval of a static or instance property.
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbPropertyExpression : DbExpression
    { 
        private EdmMember _property; 
        private ExpressionLink _instance;
 
        private void InitializeFromMember(DbCommandTree tree, EdmMember member, DbExpression instance)
        {
            //
            // Validate the instance 
            //
            if (null == instance) 
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Property_InstanceRequiredForInstance, "instance");
            } 

            TypeUsage instanceType = TypeUsage.Create(member.DeclaringType);
            _instance = new ExpressionLink("Instance", tree, instanceType, instance);
 
            Debug.Assert(!TypeSemantics.IsNullOrNullType(Helper.GetModelTypeUsage(member)), "EdmMember metadata has a TypeUsage of null or NullType");
 
            _property = member; 
            this.ResultType = Helper.GetModelTypeUsage(member);
        } 

        internal DbPropertyExpression(DbCommandTree cmdTree, EdmProperty propertyInfo, DbExpression instance)
            : base(cmdTree, DbExpressionKind.Property)
        { 
            //
            // Ensure that the property metadata is non-null and from the same metadata workspace and dataspace as the command tree. 
            // 
            cmdTree.TypeHelper.CheckMember(propertyInfo, "propertyInfo");
 
            InitializeFromMember(cmdTree, propertyInfo, instance);
        }

        internal DbPropertyExpression(DbCommandTree cmdTree, RelationshipEndMember memberInfo, DbExpression instance) 
            : base(cmdTree, DbExpressionKind.Property)
        { 
            // 
            // Ensure that the relationship end metadata is non-null and from the same metadata workspace and dataspace as the command tree.
            // 
            cmdTree.TypeHelper.CheckMember(memberInfo, "memberInfo");

            InitializeFromMember(cmdTree, memberInfo, instance);
        } 

        internal DbPropertyExpression(DbCommandTree cmdTree, NavigationProperty propertyInfo, DbExpression instance) 
            : base(cmdTree, DbExpressionKind.Property) 
        {
            // 
            // Ensure that the navigation property metadata is non-null and from the same metadata workspace and dataspace as the command tree.
            //
            cmdTree.TypeHelper.CheckMember(propertyInfo, "propertyInfo");
 
            InitializeFromMember(cmdTree, propertyInfo, instance);
        } 
 
        /// 
        /// Gets the property metadata for the property to retrieve. 
        /// 
        public EdmMember Property { get { return _property; } }

        ///  
        /// Gets or sets an  that defines the instance from which the property should be retrieved.
        ///  
        /// The expression is null 
        /// 
        ///     The expression is not associated with the DbPropertyExpression's command tree, 
        ///     or its result type is not equal or promotable to the type that defines the property
        /// 
        public DbExpression Instance
        { 
            get { return _instance.Expression; }
            /*CQT_PUBLIC_API(*/internal/*)*/ set 
            { 
                _instance.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 invocation of a function.
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbFunctionExpression : DbExpression 
    { 
        private EdmFunction _functionInfo;
        private IList _args; 
        private ExpressionLink _lambdaBody;

        internal DbFunctionExpression(DbCommandTree cmdTree, EdmFunction function, DbExpression lambdaBody, IList args)
            : base(cmdTree, DbExpressionKind.Function) 
        {
            // 
            // Ensure that the function metadata is non-null and from the same metadata workspace and dataspace as the command tree. 
            // Lambda functions are not verified since all of their components (return type, parameter types) have already been
            // checked and because they have not been added to a metadata collection because they are not directly associated with 
            // a particular metadata workspace. Iff a function is a Lambda function will the Lambda body argument be non-null.
            //
            if (null == lambdaBody)
            { 
                cmdTree.TypeHelper.CheckFunction(function);
            } 
 
            //
            // Non-composable functions or functions including command text are not permitted in expressions -- they can only be 
            // executed independently
            //
            if (!function.IsComposableAttribute)
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Function_NonComposableInExpression, "function");
            } 
 
            if (!String.IsNullOrEmpty(function.CommandTextAttribute))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Function_CommandTextInExpression, "function");
            }

            // 
            // Functions that return void are not allowed
            // 
            if (null == function.ReturnParameter || 
                TypeSemantics.IsNullOrNullType(function.ReturnParameter.TypeUsage))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Function_VoidResultInvalid, "function");
            }

            // 
            // Validate the arguments
            // 
            EntityUtil.CheckArgumentNull(args, "args"); 
            _args = new ExpressionList("Arguments", cmdTree, function.Parameters, args);
            _functionInfo = function; 

            //
            // Is this a 'Lambda' function invocation?
            // 
            if(lambdaBody != null)
            { 
                _lambdaBody = new ExpressionLink("LambdaBody", cmdTree, lambdaBody); 
            }
 
            this.ResultType = function.ReturnParameter.TypeUsage;
        }

        ///  
        /// Gets the metadata for the function to invoke.
        ///  
        public EdmFunction Function { get { return _functionInfo; } } 

        ///  
        /// Gets an  list that provides the arguments to the function.
        /// 
        public IList Arguments { get { return _args; } }
 
        /// 
        /// Gets a Boolean value indicating whether or not the function to invoke is an inline function definition (Lambda function). 
        ///  
        /*CQT_PUBLIC_API(*/internal/*)*/  bool IsLambda { get { return _lambdaBody != null; } }
 
        /// 
        /// Gets the DbExpression that provides the Body of the referenced function if that function is a Lambda function
        /// 
        /*CQT_PUBLIC_API(*/internal/*)*/ DbExpression LambdaBody 
        {
            get 
            { 
                if (_lambdaBody != null)
                { 
                    return _lambdaBody.Expression;
                }

                return null; 
            }
            set 
            { 
                if (null == _lambdaBody)
                { 
                    throw EntityUtil.NotSupported(System.Data.Entity.Strings.Cqt_Function_BodyOnlyValidForLambda);
                }

                _lambdaBody.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"); } } 

        #region Lambda function namespace and name 
 
        internal static string LambdaFunctionNameSpace { get { return "System.Data.Common.CommandTrees.LambdaFunctions"; } }
        internal static string LambdaFunctionName { get { return "Lambda"; } } 

        #endregion
    }
 
#if METHOD_EXPRESSION
    ///  
    /// Represents the invocation of a method. 
    /// 
    public sealed class MethodExpression : Expression 
    {
        MethodMetadata m_methodInfo;
        IList m_args;
        ExpressionLink m_inst; 

        internal MethodExpression(CommandTree cmdTree, MethodMetadata methodInfo, IList args, Expression instance) 
            : base(cmdTree, ExpressionKind.Method) 
        {
            // 
            // Ensure that the property metadata is non-null and from the same metadata workspace and dataspace as the command tree.
            //
            cmdTree.TypeHelper.CheckMember(methodInfo, "method", "methodInfo");
 
            //
            // Methods that return void are not allowed 
            // 
            if (cmdTree.TypeHelper.IsNullOrNullType(methodInfo.Type))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Method_VoidResultInvalid, "methodInfo");
            }

            if (null == args) 
            {
                throw EntityUtil.ArgumentNull("args"); 
            } 

            this.m_inst = new ExpressionLink("Instance", cmdTree); 

            //
            // Validate the instance
            // 
            if (methodInfo.IsStatic)
            { 
                if (instance != null) 
                {
                    throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Method_InstanceInvalidForStatic, "instance"); 
                }
            }
            else
            { 
                if (null == instance)
                { 
                    throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Method_InstanceRequiredForInstance, "instance"); 
                }
 
                this.m_inst.SetExpectedType(methodInfo.DefiningType);
                this.m_inst.InitializeValue(instance);
            }
 
            //
            // Validate the arguments 
            // 
            m_args = new ExpressionList("Arguments", cmdTree, methodInfo.Parameters, args);
            m_methodInfo = methodInfo; 
            this.ResultType = methodInfo.Type;
        }

        ///  
        /// Gets the metadata for the method to invoke.
        ///  
        public MethodMetadata Method { get { return m_methodInfo; } } 

        ///  
        /// Gets the expressions that provide the arguments to the method.
        /// 
        public IList Arguments { get { return m_args; } }
 
        /// 
        /// Gets or sets an  that defines the instance on which the method should be invoked. Must be null for instance methods. 
        /// For static properties, Instance will always be null, and attempting to set a new value will result 
        /// in .
        ///  
        /// The expression is null
        /// The method is static
        /// 
        ///     The expression is not associated with the MethodExpression's command tree, 
        ///     or its result type is not equal or promotable to the type that defines the method
        ///  
        public Expression Instance 
        {
            get { return m_inst.Expression; } 
            /*CQT_PUBLIC_API(*/internal/*)*/ set
            {
                if (this.m_methodInfo.IsStatic)
                { 
                    throw EntityUtil.NotSupported(System.Data.Entity.Strings.Cqt_Method_InstanceInvalidForStatic);
                } 
 
                this.m_inst.Expression = value;
            } 
        }

        /// 
        /// The visitor pattern method for expression visitors that do not produce a result value. 
        /// 
        /// An instance of ExpressionVisitor. 
        ///  is null 
        public override void Accept(ExpressionVisitor 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 ExpressionVisitor 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"); } }
    } 
#endif

    /// 
    /// Represents the navigation of a (composition or association) relationship given the 'from' role, the 'to' role and an instance of the from role 
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbRelationshipNavigationExpression : DbExpression 
    {
        private RelationshipType _relation; 
        private RelationshipEndMember _fromRole;
        private RelationshipEndMember _toRole;
        private ExpressionLink _from;
 
        internal DbRelationshipNavigationExpression(
            DbCommandTree cmdTree, 
            RelationshipEndMember fromEnd, 
            RelationshipEndMember toEnd,
            DbExpression from) 
            : base(cmdTree, DbExpressionKind.RelationshipNavigation)
        {
            //
            // Validate the relationship ends before use 
            //
            this.CheckEnds(fromEnd, toEnd); 
 
            RelationshipType relType = fromEnd.DeclaringType as RelationshipType;
 
            //
            // Ensure that the relation type is non-null and from the same metadata workspace as the command tree
            //
            CommandTreeTypeHelper.CheckType(relType); 

            // 
            // Validate that the 'to' relationship end is defined by the same relationship type as the 'from' end 
            //
            if (!relType.Equals(toEnd.DeclaringType)) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Factory_IncompatibleRelationEnds, "toEnd");
            }
 
            //
            // Validation was successful so initialize members and verify the source expression against the expected type 
            // 
            _relation = relType;
            _fromRole = fromEnd; 
            _toRole = toEnd;
            _from = new ExpressionLink("NavigationSource", cmdTree, GetExpectedInstanceType(fromEnd, from), from);

            this.ResultType = GetResultType(toEnd); 
        }
 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal DbRelationshipNavigationExpression(
            DbCommandTree cmdTree, 
            RelationshipType type,
            string fromEndName,
            string toEndName,
            DbExpression from) 
            : base(cmdTree, DbExpressionKind.RelationshipNavigation)
        { 
            // 
            // Verify that the from and to relation end names are not null
            // 
            EntityUtil.CheckArgumentNull(fromEndName, "fromEndName");
            EntityUtil.CheckArgumentNull(toEndName, "toEndName");

            // 
            // Ensure that the relation type is non-null and from the same metadata workspace as the command tree
            // 
            CommandTreeTypeHelper.CheckType(type); 

            // 
            // Retrieve the relation end properties with the specified 'from' and 'to' names
            //
            RelationshipEndMember fromEnd = DbRelationshipNavigationExpression.FindEnd(type.Members, fromEndName, "fromEndName");
            RelationshipEndMember toEnd = DbRelationshipNavigationExpression.FindEnd(type.Members, toEndName, "toEndName"); 

            // 
            // Validate the retrieved relation end properties 
            //
            this.CheckEnds(fromEnd, toEnd); 

            //
            // Validation was successful so initialize members and verify the source expression against the expected type
            // 
            _relation = type;
            _fromRole = fromEnd; 
            _toRole = toEnd; 
            _from = new ExpressionLink("NavigationSource", cmdTree, GetExpectedInstanceType(fromEnd, from), from);
 
            this.ResultType = GetResultType(toEnd);
        }

 
        /// 
        /// Gets the metadata for the relationship over which navigation occurs 
        ///  
        public RelationshipType Relationship { get { return _relation; } }
 
        /// 
        /// Gets the metadata for the relationship end to navigate from
        /// 
        public RelationshipEndMember NavigateFrom { get { return _fromRole; } } 

        ///  
        /// Gets the metadata for the relationship end to navigate to 
        /// 
        public RelationshipEndMember NavigateTo { get { return _toRole; } } 

        /// 
        /// Gets or sets an  that specifies the instance of the 'from' relationship end from which navigation should occur.
        ///  
        /// The expression is null
        ///  
        ///     The expression is not associated with the DbRelationshipNavigationExpression's command tree, 
        ///     or its result type is not equal or promotable to the reference type of the NavigateFrom property.
        ///  
        /// 
        public DbExpression NavigationSource { get { return _from.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _from.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"); } } 

        /// 
        /// Retrieves a relation end property from a given enumerable collection of members, given the name of the end.
        ///  
        /// The enumerable collection of members
        /// The name of the end to retrieve 
        /// The variable name to specify if an exception must be thrown 
        /// An RelationEndProperty instance that represents the relation end with the specified name
        /// If no relation end with the specified name exists 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static RelationshipEndMember FindEnd(IEnumerable members, string endName, string varName)
        {
            foreach (EdmMember member in members) 
            {
                RelationshipEndMember end = member as RelationshipEndMember; 
                if (end != null && 
                    end.Name.Equals(endName, StringComparison.Ordinal))
                { 
                    return end;
                }
            }
 
            throw EntityUtil.ArgumentOutOfRange(System.Data.Entity.Strings.Cqt_Factory_NoSuchRelationEnd, varName);
        } 
 
        private static TypeUsage GetExpectedInstanceType(RelationshipEndMember end, DbExpression from)
        { 
            TypeUsage endType = end.TypeUsage;
            if (!TypeSemantics.IsReferenceType(endType))
            {
                // 
                // The only relation end that is currently allowed to have a non-Reference type is the Child end of
                // a composition, in which case the end type must be an entity type. 
                // 
                // Debug.Assert(end.Relation.IsComposition && !end.IsParent && (end.Type is EntityType), "Relation end can only have non-Reference type if it is a Composition child end");
 
                endType = TypeHelpers.CreateReferenceTypeUsage(TypeHelpers.GetEdmType(endType));
            }

            TypeUsage retType = TypeHelpers.GetCommonTypeUsage(endType, from.ResultType); 
            if (null == retType)
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelNav_WrongSourceType(TypeHelpers.GetFullName(endType)), "from"); 
            }
 
            return retType;
        }

        private static TypeUsage GetResultType(RelationshipEndMember end) 
        {
            TypeUsage retType = end.TypeUsage; 
            if (!TypeSemantics.IsReferenceType(retType)) 
            {
                // 
                // The only relation end that is currently allowed to have a non-Reference type is the Child end of
                // a composition, in which case the end type must be an entity type.
                //
                //Debug.Assert(end.Relation.IsComposition && !end.IsParent && (end.Type is EntityType), "Relation end can only have non-Reference type if it is a Composition child end"); 

                retType = TypeHelpers.CreateReferenceTypeUsage(TypeHelpers.GetEdmType(retType)); 
            } 

            // 
            // If the upper bound is not 1 the result type is a collection of the given type
            //
            if (RelationshipMultiplicity.Many == end.RelationshipMultiplicity)
            { 
                retType = TypeHelpers.CreateCollectionTypeUsage(retType);
            } 
 
            return retType;
        } 

        private void CheckEnds(RelationshipEndMember fromEnd, RelationshipEndMember toEnd)
        {
            // 
            // Ensure that the 'from' role metadata is non-null and from the same metadata workspace as the command tree
            // 
            this.CommandTree.TypeHelper.CheckMember(fromEnd, "fromEnd"); 

            // 
            // Ensure that the 'to' role metadata is non-null and from the same metadata workspace as the command tree
            //
            this.CommandTree.TypeHelper.CheckMember(toEnd, "toEnd");
        } 
    }
 
    ///  
    /// Encapsulates the result (represented as a Ref to the resulting Entity) of navigating from
    /// the specified source end of a relationship to the specified target end. This class is intended 
    /// for use only with , where an 'owning' instance of that class
    /// represents the source Entity involved in the relationship navigation.
    /// Instances of DbRelatedEntityRef may be specified when creating a  that
    /// constructs an Entity, allowing information about Entities that are related to the newly constructed Entity to be captured. 
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    internal sealed class DbRelatedEntityRef 
    {
        private readonly RelationshipEndMember _sourceEnd; 
        private readonly RelationshipEndMember _targetEnd;
        private ExpressionLink _targetEntityRef;
        //private DbExpression _targetEntityRef;
 
        internal DbRelatedEntityRef(DbCommandTree commandTree, RelationshipEndMember sourceEnd, RelationshipEndMember targetEnd, DbExpression targetEntityRef)
        { 
            // Validate that the specified relationship ends are: 
            // 1. Non-null
            // 2. From the same metadata workspace as that used by the command tree 
            commandTree.TypeHelper.CheckMember(sourceEnd, "sourceEnd");
            commandTree.TypeHelper.CheckMember(targetEnd, "targetEnd");

            // Validate that the specified target entity ref is: 
            // 1. Non-null
            // 2. Associated with this command tree 
            _targetEntityRef = new ExpressionLink("TargetEntityReference", commandTree); 
            _targetEntityRef.InitializeValue(targetEntityRef);
 
            // Validate that the specified source and target ends are:
            // 1. Declared by the same relationship type
            if (!object.ReferenceEquals(sourceEnd.DeclaringType, targetEnd.DeclaringType))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEndFromDifferentRelationship, "targetEnd");
            } 
            // 2. Not the same end 
            if (object.ReferenceEquals(sourceEnd, targetEnd))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEndSameAsSourceEnd, "targetEnd");
            }

            // Validate that the specified target end has multiplicity of at most one 
            if (targetEnd.RelationshipMultiplicity != RelationshipMultiplicity.One &&
                targetEnd.RelationshipMultiplicity != RelationshipMultiplicity.ZeroOrOne) 
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEndMustBeAtMostOne, "targetEnd");
            } 

            // Validate that the specified target entity ref actually has a ref result type
            if (!TypeSemantics.IsReferenceType(targetEntityRef.ResultType))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEntityNotRef, "targetEntityRef");
            } 
 
            // Validate that the specified target entity is of a type that can be reached by navigating to the specified relationship end
            EntityTypeBase endType = TypeHelpers.GetEdmType(targetEnd.TypeUsage).ElementType; 
            EntityTypeBase targetType = TypeHelpers.GetEdmType(targetEntityRef.ResultType).ElementType;
            if (!endType.EdmEquals(targetType) && !TypeSemantics.IsSubTypeOf(targetType, endType))
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEntityNotCompatible, "targetEntityRef"); 
            }
 
            // Validation succeeded, initialize remaining state (_targetEntityRef is already initialized) 
            _targetEnd = targetEnd;
            _sourceEnd = sourceEnd; 
        }

        /// 
        /// Retrieves the 'source' end of the relationship navigation satisfied by this related entity Ref 
        /// 
        internal RelationshipEndMember SourceEnd { get { return _sourceEnd; } } 
 
        /// 
        /// Retrieves the 'target' end of the relationship navigation satisfied by this related entity Ref 
        /// 
        internal RelationshipEndMember TargetEnd { get { return _targetEnd; } }

        ///  
        /// Retrieves the entity Ref that is the result of navigating from the source to the target end of this related entity Ref
        ///  
        internal DbExpression TargetEntityReference { get { return _targetEntityRef.Expression; } set { _targetEntityRef.Expression = value; } } 
    }
 
    /// 
    /// Represents the construction of a new instance of a given type, including set and record types.
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbNewInstanceExpression : DbExpression
    { 
        private IList _elements; 
        private System.Collections.ObjectModel.ReadOnlyCollection _relatedEntityRefs;
 
        internal DbNewInstanceExpression(DbCommandTree cmdTree, TypeUsage type, IList args)
            : base(cmdTree, DbExpressionKind.NewInstance)
        {
            // 
            // Ensure that the type is non-null, valid and not NullType
            // 
            cmdTree.TypeHelper.CheckType(type); 

            // 
            // Type-specific validation
            //
            CollectionType collectionType = null;
            if( TypeHelpers.TryGetEdmType(type, out collectionType) && 
                collectionType != null)
            { 
                TypeUsage elementType = collectionType.TypeUsage; 

                // 
                // Is this an empty collection constructor?
                //
                if (null == args || 0 == args.Count)
                { 
                    _elements = new ExpressionList("Arguments", cmdTree, 0);
                } 
                else 
                {
                    _elements = new ExpressionList("Arguments", cmdTree, elementType, args); 
                }
            }
            else
            { 
                EntityUtil.CheckArgumentNull(args, "args");
                _elements = CreateStructuralArgumentList(cmdTree, type, type.EdmType as StructuralType, args); 
            } 

            this.ResultType = type; 
        }

        internal DbNewInstanceExpression(DbCommandTree cmdTree, EntityType entityType, IList attributeValues, IList relationships)
            : base(cmdTree, DbExpressionKind.NewInstance) 
        {
            EntityUtil.CheckArgumentNull(entityType, "entityType"); 
            EntityUtil.CheckArgumentNull(attributeValues, "attributeValues"); 
            EntityUtil.CheckArgumentNull(relationships, "relationships");
 
            TypeUsage resultType = CommandTreeTypeHelper.CreateResultType(entityType);
            cmdTree.TypeHelper.CheckType(resultType, "entityType");

            _elements = CreateStructuralArgumentList(cmdTree, resultType, entityType, attributeValues); 

            if (relationships.Count > 0) 
            { 
                List relatedRefs = new List(relationships.Count);
                for (int idx = 0; idx < relationships.Count; idx++) 
                {
                    DbRelatedEntityRef relatedRef = relationships[idx];
                    EntityUtil.CheckArgumentNull(relatedRef, CommandTreeUtils.FormatIndex("relationships", idx));
 
                    // The target entity ref must be associated with the same command tree as this new instance expression
                    if (!object.ReferenceEquals(relatedRef.TargetEntityReference.CommandTree, cmdTree)) 
                    { 
                        throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_IncompatibleRelatedEntity_TargetEntityNotValid, CommandTreeUtils.FormatIndex("relationships", idx));
                    } 

                    // The source end type must be the same type or a supertype of the Entity instance type
                    EntityTypeBase expectedSourceType = TypeHelpers.GetEdmType(relatedRef.SourceEnd.TypeUsage).ElementType;
                    if (!entityType.EdmEquals(expectedSourceType) && 
                       !entityType.IsSubtypeOf(expectedSourceType))
                    { 
                        throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_IncompatibleRelatedEntity_SourceTypeNotValid, CommandTreeUtils.FormatIndex("relationships", idx)); 
                    }
 
                    relatedRefs.Add(relatedRef);
                }
                _relatedEntityRefs = relatedRefs.AsReadOnly();
            } 

            this.ResultType = resultType; 
        } 

        ///  
        /// Gets an  list that provides the property/column values or set elements for the new instance.
        /// 
        public IList Arguments { get { return _elements; } }
 
        /// 
        /// 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"); } }


        internal bool HasRelatedEntityReferences { get { return (_relatedEntityRefs != null); } } 

        ///  
        /// Gets the related entity references (if any) for an entity constructor. 
        /// May be null if no related entities were specified - use the  property to determine this.
        ///  
        internal System.Collections.ObjectModel.ReadOnlyCollection RelatedEntityReferences { get { return _relatedEntityRefs; } }

        private static IList CreateStructuralArgumentList(DbCommandTree cmdTree, TypeUsage type, StructuralType structType, IList args)
        { 
            if (null == structType)
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_StructuralTypeRequired, "type"); 
            }
 
            if (structType.Members.Count < 1)
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_CannotInstantiateMemberlessType(TypeHelpers.GetFullName(type)), "type");
            } 

            if (structType.Abstract) 
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_CannotInstantiateAbstractType(TypeHelpers.GetFullName(type)), "type");
            } 

            return new ExpressionList("Arguments",
                                      cmdTree,
                                      TypeHelpers.GetAllStructuralMembers(structType), 
                                      args);
        } 
    } 

    ///  
    /// Represents a (strongly typed) reference to a specific instance within a given entity set.
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbRefExpression : DbUnaryExpression 
    {
        EntitySet _entitySet; 
 
        internal DbRefExpression(DbCommandTree cmdTree, EntitySet entitySet, DbExpression refKeys, EntityType entityType)
            : base(cmdTree, DbExpressionKind.Ref) 
        {
            EntityUtil.CheckArgumentNull(entitySet, "entitySet");
            EntityUtil.CheckArgumentNull(refKeys, "refKeys");
 
            CommandTreeTypeHelper.CheckType(entityType);
            cmdTree.TypeHelper.CheckEntitySet(entitySet); 
 
            //
            // Verify that the specified return type of the Ref operation is actually in 
            // the same hierarchy as the Entity type of the specified Entity set.
            //
            if (!TypeSemantics.IsValidPolymorphicCast(entitySet.ElementType, entityType))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Ref_PolymorphicArgRequired);
            } 
 
            //
            // The Argument DbExpression must construct a set of values of the same types as the Key members of the Entity 
            // The names of the columns in the record type constructed by the Argument are not important, only that the
            // number of columns is the same as the number of Key members and that for each Key member the corresponding
            // column (based on order) is of a promotable type.
            // To enforce this the ArgumentLink ExpressionLink's ExpectedType is initialized to a record type based on the 
            // names and types of the Key members. Since the promotability check used in ExpressionLink will ignore the names
            // of the ExpectedType's columns, ExpressionLink will therefore enforce the required level of type correctness 
            // on the argument expression both here when it's value is first set (by calling ArgumentLink.InitializeValue) 
            // and subsequently when the value of the Argument property is set to a new value.
            // 
            // Set the expected type to be the record type created based on the Key members
            //
            TypeUsage keyType = CommandTreeTypeHelper.CreateResultType(TypeHelpers.CreateKeyRowType(entitySet.ElementType, cmdTree.MetadataWorkspace));
            this.ArgumentLink.SetExpectedType(keyType); 

            // 
            // Attempt to initialize the Argument to the specified DbExpression. 
            // If the type is not promotable to the record type set above (i.e. does
            // not have the same number of columns, with the type of each corresponding 
            // column promotable to the column type of the record's column, names ignored)
            // then the ExpressionLink will throw at this point.
            //
            this.ArgumentLink.InitializeValue(refKeys); 

            cmdTree.TrackContainer(entitySet.EntityContainer); 
 
            // Initialize the entitySet and result type properties.
            // The result type of the expression is Ref. 
            _entitySet = entitySet;
            this.ResultType = CommandTreeTypeHelper.CreateReferenceResultType(entityType);
        }
 
        /// 
        /// Gets the metadata for the entity set that contains the instance. 
        ///  
        public EntitySet EntitySet { get { return _entitySet; } }
 
        /// 
        /// 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 retrieval of a given entity using the specified Ref.
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Deref"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbDerefExpression : DbUnaryExpression 
    {
        internal DbDerefExpression(DbCommandTree cmdTree, DbExpression refExpr) 
            : base(cmdTree, DbExpressionKind.Deref, refExpr) 
        {
            // 
            // Ensure that the operand is actually of a reference type.
            //
            EntityType entityType;
            if(!TypeHelpers.TryGetRefEntityType(this.Argument.ResultType, out entityType)) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_DeRef_RefRequired, "Argument"); 
            } 

            // 
            // Result Type is the element type of the reference type
            //
            this.ResultType = CommandTreeTypeHelper.CreateResultType(entityType);
        } 

        ///  
        /// 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 'scan' of all elements of a given entity set. 
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbScanExpression : DbExpression 
    {
        private EntitySetBase _targetSet;

        internal DbScanExpression(DbCommandTree cmdTree, EntitySetBase entitySet) 
            : base(cmdTree, DbExpressionKind.Scan)
        { 
            cmdTree.TypeHelper.CheckEntitySet(entitySet); 
            cmdTree.TrackContainer(entitySet.EntityContainer);
 
            _targetSet = entitySet;
            this.ResultType = CommandTreeTypeHelper.CreateCollectionResultType(entitySet.ElementType);
        }
 
        /// 
        /// Gets the metadata for the referenced entity or relationship set. 
        ///  
        public EntitySetBase Target { get { return _targetSet; } }
 
        /// 
        /// 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.Diagnostics;
using System.Globalization;

using System.Data.Common; 
using System.Data.Metadata.Edm;
using System.Data.Common.CommandTrees.Internal; 
 
namespace System.Data.Common.CommandTrees
{ 
    /// 
    /// Represents a constant value.
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbConstantExpression : DbExpression
    { 
        private object _value; 

        internal DbConstantExpression(DbCommandTree commandTree, object value) 
            : base(commandTree, DbExpressionKind.Constant)
        {
            if (null == value)
            { 
                throw EntityUtil.ArgumentNull("value");
            } 
 
            //
            // Check that typeof(value) is actually a valid constant (i.e. primitive) type 
            //
            PrimitiveTypeKind primitiveTypeKind;
            if (!CommandTreeUtils.TryGetPrimtiveTypeKind(value.GetType(), out primitiveTypeKind))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Constant_InvalidType, "value");
            } 
 
            TypeUsage typeMeta = TypeHelpers.GetLiteralTypeUsage(primitiveTypeKind);
 
            //
            // Set the value
            //
            _value = value; 
            this.ResultType = typeMeta;
        } 
 
        internal DbConstantExpression(DbCommandTree commandTree, object value, TypeUsage constantType)
            : base(commandTree, DbExpressionKind.Constant) 
        {
            //
            // Basic validation of constant value and constant type (non-null, read-only, etc)
            // 
            EntityUtil.CheckArgumentNull(value, "value");
            commandTree.TypeHelper.CheckType(constantType, "constantType"); 
 
            //
            // Verify that constantType is a primitive type and that value is an instance of that primitive type 
            // Note that the value is not validated against applicable facets (such as MaxLength for a string value),
            // this is left to the server.
            //
            PrimitiveType primitiveType; 
            if (!TypeHelpers.TryGetEdmType(constantType, out primitiveType))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Constant_InvalidConstantType(constantType.ToString()), "constantType"); 
            }
 
            PrimitiveTypeKind valueKind;
            if (!CommandTreeUtils.TryGetPrimtiveTypeKind(value.GetType(), out valueKind) ||
                primitiveType.PrimitiveTypeKind != valueKind)
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Constant_InvalidValueForType(constantType.ToString()), "value");
            } 
 
            //
            // Set the value 
            //
            _value = value;
            this.ResultType = constantType;
        } 

        ///  
        /// Gets the constant value. 
        /// 
        public object Value { get { return _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 null.
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbNullExpression : DbExpression
    { 
        internal DbNullExpression(DbCommandTree commandTree, TypeUsage type) 
            : base(commandTree, DbExpressionKind.Null)
        { 
            commandTree.TypeHelper.CheckType(type);
            this.ResultType = type;
        }
 
        /// 
        /// 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 reference to a variable that is currently in scope.
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbVariableReferenceExpression : DbExpression
    { 
        private string _name;

        internal DbVariableReferenceExpression(DbCommandTree cmdTree, TypeUsage type, string name)
            : base(cmdTree, DbExpressionKind.VariableReference) 
        {
            if (string.IsNullOrEmpty(name)) 
            { 
                throw EntityUtil.ArgumentNull("name");
            } 

            //
            // Verify the type of the reference. NullType is not allowed in Var or Parameter references.
            // 
            cmdTree.TypeHelper.CheckType(type);
 
            _name = name; 
            this.ResultType = type;
        } 

        /// 
        /// Gets the name of the referenced variable.
        ///  
        public string VariableName { get { return _name; } }
 
        ///  
        /// 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 reference to a parameter declared on the command tree that contains this expression. 
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbParameterReferenceExpression : DbExpression
    {
        private string _name;
 
        internal DbParameterReferenceExpression(DbCommandTree cmdTree, TypeUsage type, string name)
            : base(cmdTree, DbExpressionKind.ParameterReference) 
        { 
            EntityUtil.CheckArgumentNull(name, "name");
 
            // DbCommandTree.CreateParameterRefExpression should check that a parameter with the given name exists,
            // and DbCommandTree.AddParameter should have already verified that the name is valid, so this need only
            // be asserted here.
            Debug.Assert(DbCommandTree.IsValidParameterName(name), string.Format(CultureInfo.InvariantCulture, "Invalid parameter name passed to DbParameterReferenceExpression constructor: '{0}'", name)); 

            // 
            // Verify the type of the reference. NullType is not allowed in Var or Parameter references. 
            //
            cmdTree.TypeHelper.CheckType(type); 

            _name = name;
            this.ResultType = type;
        } 

        ///  
        /// Gets the name of the referenced parameter. 
        /// 
        public string ParameterName { get { return _name; } } 

        /// 
        /// 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 retrieval of a static or instance property.
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbPropertyExpression : DbExpression
    { 
        private EdmMember _property; 
        private ExpressionLink _instance;
 
        private void InitializeFromMember(DbCommandTree tree, EdmMember member, DbExpression instance)
        {
            //
            // Validate the instance 
            //
            if (null == instance) 
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Property_InstanceRequiredForInstance, "instance");
            } 

            TypeUsage instanceType = TypeUsage.Create(member.DeclaringType);
            _instance = new ExpressionLink("Instance", tree, instanceType, instance);
 
            Debug.Assert(!TypeSemantics.IsNullOrNullType(Helper.GetModelTypeUsage(member)), "EdmMember metadata has a TypeUsage of null or NullType");
 
            _property = member; 
            this.ResultType = Helper.GetModelTypeUsage(member);
        } 

        internal DbPropertyExpression(DbCommandTree cmdTree, EdmProperty propertyInfo, DbExpression instance)
            : base(cmdTree, DbExpressionKind.Property)
        { 
            //
            // Ensure that the property metadata is non-null and from the same metadata workspace and dataspace as the command tree. 
            // 
            cmdTree.TypeHelper.CheckMember(propertyInfo, "propertyInfo");
 
            InitializeFromMember(cmdTree, propertyInfo, instance);
        }

        internal DbPropertyExpression(DbCommandTree cmdTree, RelationshipEndMember memberInfo, DbExpression instance) 
            : base(cmdTree, DbExpressionKind.Property)
        { 
            // 
            // Ensure that the relationship end metadata is non-null and from the same metadata workspace and dataspace as the command tree.
            // 
            cmdTree.TypeHelper.CheckMember(memberInfo, "memberInfo");

            InitializeFromMember(cmdTree, memberInfo, instance);
        } 

        internal DbPropertyExpression(DbCommandTree cmdTree, NavigationProperty propertyInfo, DbExpression instance) 
            : base(cmdTree, DbExpressionKind.Property) 
        {
            // 
            // Ensure that the navigation property metadata is non-null and from the same metadata workspace and dataspace as the command tree.
            //
            cmdTree.TypeHelper.CheckMember(propertyInfo, "propertyInfo");
 
            InitializeFromMember(cmdTree, propertyInfo, instance);
        } 
 
        /// 
        /// Gets the property metadata for the property to retrieve. 
        /// 
        public EdmMember Property { get { return _property; } }

        ///  
        /// Gets or sets an  that defines the instance from which the property should be retrieved.
        ///  
        /// The expression is null 
        /// 
        ///     The expression is not associated with the DbPropertyExpression's command tree, 
        ///     or its result type is not equal or promotable to the type that defines the property
        /// 
        public DbExpression Instance
        { 
            get { return _instance.Expression; }
            /*CQT_PUBLIC_API(*/internal/*)*/ set 
            { 
                _instance.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 invocation of a function.
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbFunctionExpression : DbExpression 
    { 
        private EdmFunction _functionInfo;
        private IList _args; 
        private ExpressionLink _lambdaBody;

        internal DbFunctionExpression(DbCommandTree cmdTree, EdmFunction function, DbExpression lambdaBody, IList args)
            : base(cmdTree, DbExpressionKind.Function) 
        {
            // 
            // Ensure that the function metadata is non-null and from the same metadata workspace and dataspace as the command tree. 
            // Lambda functions are not verified since all of their components (return type, parameter types) have already been
            // checked and because they have not been added to a metadata collection because they are not directly associated with 
            // a particular metadata workspace. Iff a function is a Lambda function will the Lambda body argument be non-null.
            //
            if (null == lambdaBody)
            { 
                cmdTree.TypeHelper.CheckFunction(function);
            } 
 
            //
            // Non-composable functions or functions including command text are not permitted in expressions -- they can only be 
            // executed independently
            //
            if (!function.IsComposableAttribute)
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Function_NonComposableInExpression, "function");
            } 
 
            if (!String.IsNullOrEmpty(function.CommandTextAttribute))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Function_CommandTextInExpression, "function");
            }

            // 
            // Functions that return void are not allowed
            // 
            if (null == function.ReturnParameter || 
                TypeSemantics.IsNullOrNullType(function.ReturnParameter.TypeUsage))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Function_VoidResultInvalid, "function");
            }

            // 
            // Validate the arguments
            // 
            EntityUtil.CheckArgumentNull(args, "args"); 
            _args = new ExpressionList("Arguments", cmdTree, function.Parameters, args);
            _functionInfo = function; 

            //
            // Is this a 'Lambda' function invocation?
            // 
            if(lambdaBody != null)
            { 
                _lambdaBody = new ExpressionLink("LambdaBody", cmdTree, lambdaBody); 
            }
 
            this.ResultType = function.ReturnParameter.TypeUsage;
        }

        ///  
        /// Gets the metadata for the function to invoke.
        ///  
        public EdmFunction Function { get { return _functionInfo; } } 

        ///  
        /// Gets an  list that provides the arguments to the function.
        /// 
        public IList Arguments { get { return _args; } }
 
        /// 
        /// Gets a Boolean value indicating whether or not the function to invoke is an inline function definition (Lambda function). 
        ///  
        /*CQT_PUBLIC_API(*/internal/*)*/  bool IsLambda { get { return _lambdaBody != null; } }
 
        /// 
        /// Gets the DbExpression that provides the Body of the referenced function if that function is a Lambda function
        /// 
        /*CQT_PUBLIC_API(*/internal/*)*/ DbExpression LambdaBody 
        {
            get 
            { 
                if (_lambdaBody != null)
                { 
                    return _lambdaBody.Expression;
                }

                return null; 
            }
            set 
            { 
                if (null == _lambdaBody)
                { 
                    throw EntityUtil.NotSupported(System.Data.Entity.Strings.Cqt_Function_BodyOnlyValidForLambda);
                }

                _lambdaBody.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"); } } 

        #region Lambda function namespace and name 
 
        internal static string LambdaFunctionNameSpace { get { return "System.Data.Common.CommandTrees.LambdaFunctions"; } }
        internal static string LambdaFunctionName { get { return "Lambda"; } } 

        #endregion
    }
 
#if METHOD_EXPRESSION
    ///  
    /// Represents the invocation of a method. 
    /// 
    public sealed class MethodExpression : Expression 
    {
        MethodMetadata m_methodInfo;
        IList m_args;
        ExpressionLink m_inst; 

        internal MethodExpression(CommandTree cmdTree, MethodMetadata methodInfo, IList args, Expression instance) 
            : base(cmdTree, ExpressionKind.Method) 
        {
            // 
            // Ensure that the property metadata is non-null and from the same metadata workspace and dataspace as the command tree.
            //
            cmdTree.TypeHelper.CheckMember(methodInfo, "method", "methodInfo");
 
            //
            // Methods that return void are not allowed 
            // 
            if (cmdTree.TypeHelper.IsNullOrNullType(methodInfo.Type))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Method_VoidResultInvalid, "methodInfo");
            }

            if (null == args) 
            {
                throw EntityUtil.ArgumentNull("args"); 
            } 

            this.m_inst = new ExpressionLink("Instance", cmdTree); 

            //
            // Validate the instance
            // 
            if (methodInfo.IsStatic)
            { 
                if (instance != null) 
                {
                    throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Method_InstanceInvalidForStatic, "instance"); 
                }
            }
            else
            { 
                if (null == instance)
                { 
                    throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Method_InstanceRequiredForInstance, "instance"); 
                }
 
                this.m_inst.SetExpectedType(methodInfo.DefiningType);
                this.m_inst.InitializeValue(instance);
            }
 
            //
            // Validate the arguments 
            // 
            m_args = new ExpressionList("Arguments", cmdTree, methodInfo.Parameters, args);
            m_methodInfo = methodInfo; 
            this.ResultType = methodInfo.Type;
        }

        ///  
        /// Gets the metadata for the method to invoke.
        ///  
        public MethodMetadata Method { get { return m_methodInfo; } } 

        ///  
        /// Gets the expressions that provide the arguments to the method.
        /// 
        public IList Arguments { get { return m_args; } }
 
        /// 
        /// Gets or sets an  that defines the instance on which the method should be invoked. Must be null for instance methods. 
        /// For static properties, Instance will always be null, and attempting to set a new value will result 
        /// in .
        ///  
        /// The expression is null
        /// The method is static
        /// 
        ///     The expression is not associated with the MethodExpression's command tree, 
        ///     or its result type is not equal or promotable to the type that defines the method
        ///  
        public Expression Instance 
        {
            get { return m_inst.Expression; } 
            /*CQT_PUBLIC_API(*/internal/*)*/ set
            {
                if (this.m_methodInfo.IsStatic)
                { 
                    throw EntityUtil.NotSupported(System.Data.Entity.Strings.Cqt_Method_InstanceInvalidForStatic);
                } 
 
                this.m_inst.Expression = value;
            } 
        }

        /// 
        /// The visitor pattern method for expression visitors that do not produce a result value. 
        /// 
        /// An instance of ExpressionVisitor. 
        ///  is null 
        public override void Accept(ExpressionVisitor 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 ExpressionVisitor 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"); } }
    } 
#endif

    /// 
    /// Represents the navigation of a (composition or association) relationship given the 'from' role, the 'to' role and an instance of the from role 
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbRelationshipNavigationExpression : DbExpression 
    {
        private RelationshipType _relation; 
        private RelationshipEndMember _fromRole;
        private RelationshipEndMember _toRole;
        private ExpressionLink _from;
 
        internal DbRelationshipNavigationExpression(
            DbCommandTree cmdTree, 
            RelationshipEndMember fromEnd, 
            RelationshipEndMember toEnd,
            DbExpression from) 
            : base(cmdTree, DbExpressionKind.RelationshipNavigation)
        {
            //
            // Validate the relationship ends before use 
            //
            this.CheckEnds(fromEnd, toEnd); 
 
            RelationshipType relType = fromEnd.DeclaringType as RelationshipType;
 
            //
            // Ensure that the relation type is non-null and from the same metadata workspace as the command tree
            //
            CommandTreeTypeHelper.CheckType(relType); 

            // 
            // Validate that the 'to' relationship end is defined by the same relationship type as the 'from' end 
            //
            if (!relType.Equals(toEnd.DeclaringType)) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Factory_IncompatibleRelationEnds, "toEnd");
            }
 
            //
            // Validation was successful so initialize members and verify the source expression against the expected type 
            // 
            _relation = relType;
            _fromRole = fromEnd; 
            _toRole = toEnd;
            _from = new ExpressionLink("NavigationSource", cmdTree, GetExpectedInstanceType(fromEnd, from), from);

            this.ResultType = GetResultType(toEnd); 
        }
 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal DbRelationshipNavigationExpression(
            DbCommandTree cmdTree, 
            RelationshipType type,
            string fromEndName,
            string toEndName,
            DbExpression from) 
            : base(cmdTree, DbExpressionKind.RelationshipNavigation)
        { 
            // 
            // Verify that the from and to relation end names are not null
            // 
            EntityUtil.CheckArgumentNull(fromEndName, "fromEndName");
            EntityUtil.CheckArgumentNull(toEndName, "toEndName");

            // 
            // Ensure that the relation type is non-null and from the same metadata workspace as the command tree
            // 
            CommandTreeTypeHelper.CheckType(type); 

            // 
            // Retrieve the relation end properties with the specified 'from' and 'to' names
            //
            RelationshipEndMember fromEnd = DbRelationshipNavigationExpression.FindEnd(type.Members, fromEndName, "fromEndName");
            RelationshipEndMember toEnd = DbRelationshipNavigationExpression.FindEnd(type.Members, toEndName, "toEndName"); 

            // 
            // Validate the retrieved relation end properties 
            //
            this.CheckEnds(fromEnd, toEnd); 

            //
            // Validation was successful so initialize members and verify the source expression against the expected type
            // 
            _relation = type;
            _fromRole = fromEnd; 
            _toRole = toEnd; 
            _from = new ExpressionLink("NavigationSource", cmdTree, GetExpectedInstanceType(fromEnd, from), from);
 
            this.ResultType = GetResultType(toEnd);
        }

 
        /// 
        /// Gets the metadata for the relationship over which navigation occurs 
        ///  
        public RelationshipType Relationship { get { return _relation; } }
 
        /// 
        /// Gets the metadata for the relationship end to navigate from
        /// 
        public RelationshipEndMember NavigateFrom { get { return _fromRole; } } 

        ///  
        /// Gets the metadata for the relationship end to navigate to 
        /// 
        public RelationshipEndMember NavigateTo { get { return _toRole; } } 

        /// 
        /// Gets or sets an  that specifies the instance of the 'from' relationship end from which navigation should occur.
        ///  
        /// The expression is null
        ///  
        ///     The expression is not associated with the DbRelationshipNavigationExpression's command tree, 
        ///     or its result type is not equal or promotable to the reference type of the NavigateFrom property.
        ///  
        /// 
        public DbExpression NavigationSource { get { return _from.Expression; } /*CQT_PUBLIC_API(*/internal/*)*/ set { _from.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"); } } 

        /// 
        /// Retrieves a relation end property from a given enumerable collection of members, given the name of the end.
        ///  
        /// The enumerable collection of members
        /// The name of the end to retrieve 
        /// The variable name to specify if an exception must be thrown 
        /// An RelationEndProperty instance that represents the relation end with the specified name
        /// If no relation end with the specified name exists 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static RelationshipEndMember FindEnd(IEnumerable members, string endName, string varName)
        {
            foreach (EdmMember member in members) 
            {
                RelationshipEndMember end = member as RelationshipEndMember; 
                if (end != null && 
                    end.Name.Equals(endName, StringComparison.Ordinal))
                { 
                    return end;
                }
            }
 
            throw EntityUtil.ArgumentOutOfRange(System.Data.Entity.Strings.Cqt_Factory_NoSuchRelationEnd, varName);
        } 
 
        private static TypeUsage GetExpectedInstanceType(RelationshipEndMember end, DbExpression from)
        { 
            TypeUsage endType = end.TypeUsage;
            if (!TypeSemantics.IsReferenceType(endType))
            {
                // 
                // The only relation end that is currently allowed to have a non-Reference type is the Child end of
                // a composition, in which case the end type must be an entity type. 
                // 
                // Debug.Assert(end.Relation.IsComposition && !end.IsParent && (end.Type is EntityType), "Relation end can only have non-Reference type if it is a Composition child end");
 
                endType = TypeHelpers.CreateReferenceTypeUsage(TypeHelpers.GetEdmType(endType));
            }

            TypeUsage retType = TypeHelpers.GetCommonTypeUsage(endType, from.ResultType); 
            if (null == retType)
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelNav_WrongSourceType(TypeHelpers.GetFullName(endType)), "from"); 
            }
 
            return retType;
        }

        private static TypeUsage GetResultType(RelationshipEndMember end) 
        {
            TypeUsage retType = end.TypeUsage; 
            if (!TypeSemantics.IsReferenceType(retType)) 
            {
                // 
                // The only relation end that is currently allowed to have a non-Reference type is the Child end of
                // a composition, in which case the end type must be an entity type.
                //
                //Debug.Assert(end.Relation.IsComposition && !end.IsParent && (end.Type is EntityType), "Relation end can only have non-Reference type if it is a Composition child end"); 

                retType = TypeHelpers.CreateReferenceTypeUsage(TypeHelpers.GetEdmType(retType)); 
            } 

            // 
            // If the upper bound is not 1 the result type is a collection of the given type
            //
            if (RelationshipMultiplicity.Many == end.RelationshipMultiplicity)
            { 
                retType = TypeHelpers.CreateCollectionTypeUsage(retType);
            } 
 
            return retType;
        } 

        private void CheckEnds(RelationshipEndMember fromEnd, RelationshipEndMember toEnd)
        {
            // 
            // Ensure that the 'from' role metadata is non-null and from the same metadata workspace as the command tree
            // 
            this.CommandTree.TypeHelper.CheckMember(fromEnd, "fromEnd"); 

            // 
            // Ensure that the 'to' role metadata is non-null and from the same metadata workspace as the command tree
            //
            this.CommandTree.TypeHelper.CheckMember(toEnd, "toEnd");
        } 
    }
 
    ///  
    /// Encapsulates the result (represented as a Ref to the resulting Entity) of navigating from
    /// the specified source end of a relationship to the specified target end. This class is intended 
    /// for use only with , where an 'owning' instance of that class
    /// represents the source Entity involved in the relationship navigation.
    /// Instances of DbRelatedEntityRef may be specified when creating a  that
    /// constructs an Entity, allowing information about Entities that are related to the newly constructed Entity to be captured. 
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    internal sealed class DbRelatedEntityRef 
    {
        private readonly RelationshipEndMember _sourceEnd; 
        private readonly RelationshipEndMember _targetEnd;
        private ExpressionLink _targetEntityRef;
        //private DbExpression _targetEntityRef;
 
        internal DbRelatedEntityRef(DbCommandTree commandTree, RelationshipEndMember sourceEnd, RelationshipEndMember targetEnd, DbExpression targetEntityRef)
        { 
            // Validate that the specified relationship ends are: 
            // 1. Non-null
            // 2. From the same metadata workspace as that used by the command tree 
            commandTree.TypeHelper.CheckMember(sourceEnd, "sourceEnd");
            commandTree.TypeHelper.CheckMember(targetEnd, "targetEnd");

            // Validate that the specified target entity ref is: 
            // 1. Non-null
            // 2. Associated with this command tree 
            _targetEntityRef = new ExpressionLink("TargetEntityReference", commandTree); 
            _targetEntityRef.InitializeValue(targetEntityRef);
 
            // Validate that the specified source and target ends are:
            // 1. Declared by the same relationship type
            if (!object.ReferenceEquals(sourceEnd.DeclaringType, targetEnd.DeclaringType))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEndFromDifferentRelationship, "targetEnd");
            } 
            // 2. Not the same end 
            if (object.ReferenceEquals(sourceEnd, targetEnd))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEndSameAsSourceEnd, "targetEnd");
            }

            // Validate that the specified target end has multiplicity of at most one 
            if (targetEnd.RelationshipMultiplicity != RelationshipMultiplicity.One &&
                targetEnd.RelationshipMultiplicity != RelationshipMultiplicity.ZeroOrOne) 
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEndMustBeAtMostOne, "targetEnd");
            } 

            // Validate that the specified target entity ref actually has a ref result type
            if (!TypeSemantics.IsReferenceType(targetEntityRef.ResultType))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEntityNotRef, "targetEntityRef");
            } 
 
            // Validate that the specified target entity is of a type that can be reached by navigating to the specified relationship end
            EntityTypeBase endType = TypeHelpers.GetEdmType(targetEnd.TypeUsage).ElementType; 
            EntityTypeBase targetType = TypeHelpers.GetEdmType(targetEntityRef.ResultType).ElementType;
            if (!endType.EdmEquals(targetType) && !TypeSemantics.IsSubTypeOf(targetType, endType))
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEntityNotCompatible, "targetEntityRef"); 
            }
 
            // Validation succeeded, initialize remaining state (_targetEntityRef is already initialized) 
            _targetEnd = targetEnd;
            _sourceEnd = sourceEnd; 
        }

        /// 
        /// Retrieves the 'source' end of the relationship navigation satisfied by this related entity Ref 
        /// 
        internal RelationshipEndMember SourceEnd { get { return _sourceEnd; } } 
 
        /// 
        /// Retrieves the 'target' end of the relationship navigation satisfied by this related entity Ref 
        /// 
        internal RelationshipEndMember TargetEnd { get { return _targetEnd; } }

        ///  
        /// Retrieves the entity Ref that is the result of navigating from the source to the target end of this related entity Ref
        ///  
        internal DbExpression TargetEntityReference { get { return _targetEntityRef.Expression; } set { _targetEntityRef.Expression = value; } } 
    }
 
    /// 
    /// Represents the construction of a new instance of a given type, including set and record types.
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")] 
    public sealed class DbNewInstanceExpression : DbExpression
    { 
        private IList _elements; 
        private System.Collections.ObjectModel.ReadOnlyCollection _relatedEntityRefs;
 
        internal DbNewInstanceExpression(DbCommandTree cmdTree, TypeUsage type, IList args)
            : base(cmdTree, DbExpressionKind.NewInstance)
        {
            // 
            // Ensure that the type is non-null, valid and not NullType
            // 
            cmdTree.TypeHelper.CheckType(type); 

            // 
            // Type-specific validation
            //
            CollectionType collectionType = null;
            if( TypeHelpers.TryGetEdmType(type, out collectionType) && 
                collectionType != null)
            { 
                TypeUsage elementType = collectionType.TypeUsage; 

                // 
                // Is this an empty collection constructor?
                //
                if (null == args || 0 == args.Count)
                { 
                    _elements = new ExpressionList("Arguments", cmdTree, 0);
                } 
                else 
                {
                    _elements = new ExpressionList("Arguments", cmdTree, elementType, args); 
                }
            }
            else
            { 
                EntityUtil.CheckArgumentNull(args, "args");
                _elements = CreateStructuralArgumentList(cmdTree, type, type.EdmType as StructuralType, args); 
            } 

            this.ResultType = type; 
        }

        internal DbNewInstanceExpression(DbCommandTree cmdTree, EntityType entityType, IList attributeValues, IList relationships)
            : base(cmdTree, DbExpressionKind.NewInstance) 
        {
            EntityUtil.CheckArgumentNull(entityType, "entityType"); 
            EntityUtil.CheckArgumentNull(attributeValues, "attributeValues"); 
            EntityUtil.CheckArgumentNull(relationships, "relationships");
 
            TypeUsage resultType = CommandTreeTypeHelper.CreateResultType(entityType);
            cmdTree.TypeHelper.CheckType(resultType, "entityType");

            _elements = CreateStructuralArgumentList(cmdTree, resultType, entityType, attributeValues); 

            if (relationships.Count > 0) 
            { 
                List relatedRefs = new List(relationships.Count);
                for (int idx = 0; idx < relationships.Count; idx++) 
                {
                    DbRelatedEntityRef relatedRef = relationships[idx];
                    EntityUtil.CheckArgumentNull(relatedRef, CommandTreeUtils.FormatIndex("relationships", idx));
 
                    // The target entity ref must be associated with the same command tree as this new instance expression
                    if (!object.ReferenceEquals(relatedRef.TargetEntityReference.CommandTree, cmdTree)) 
                    { 
                        throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_IncompatibleRelatedEntity_TargetEntityNotValid, CommandTreeUtils.FormatIndex("relationships", idx));
                    } 

                    // The source end type must be the same type or a supertype of the Entity instance type
                    EntityTypeBase expectedSourceType = TypeHelpers.GetEdmType(relatedRef.SourceEnd.TypeUsage).ElementType;
                    if (!entityType.EdmEquals(expectedSourceType) && 
                       !entityType.IsSubtypeOf(expectedSourceType))
                    { 
                        throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_IncompatibleRelatedEntity_SourceTypeNotValid, CommandTreeUtils.FormatIndex("relationships", idx)); 
                    }
 
                    relatedRefs.Add(relatedRef);
                }
                _relatedEntityRefs = relatedRefs.AsReadOnly();
            } 

            this.ResultType = resultType; 
        } 

        ///  
        /// Gets an  list that provides the property/column values or set elements for the new instance.
        /// 
        public IList Arguments { get { return _elements; } }
 
        /// 
        /// 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"); } }


        internal bool HasRelatedEntityReferences { get { return (_relatedEntityRefs != null); } } 

        ///  
        /// Gets the related entity references (if any) for an entity constructor. 
        /// May be null if no related entities were specified - use the  property to determine this.
        ///  
        internal System.Collections.ObjectModel.ReadOnlyCollection RelatedEntityReferences { get { return _relatedEntityRefs; } }

        private static IList CreateStructuralArgumentList(DbCommandTree cmdTree, TypeUsage type, StructuralType structType, IList args)
        { 
            if (null == structType)
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_StructuralTypeRequired, "type"); 
            }
 
            if (structType.Members.Count < 1)
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_CannotInstantiateMemberlessType(TypeHelpers.GetFullName(type)), "type");
            } 

            if (structType.Abstract) 
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_NewInstance_CannotInstantiateAbstractType(TypeHelpers.GetFullName(type)), "type");
            } 

            return new ExpressionList("Arguments",
                                      cmdTree,
                                      TypeHelpers.GetAllStructuralMembers(structType), 
                                      args);
        } 
    } 

    ///  
    /// Represents a (strongly typed) reference to a specific instance within a given entity set.
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbRefExpression : DbUnaryExpression 
    {
        EntitySet _entitySet; 
 
        internal DbRefExpression(DbCommandTree cmdTree, EntitySet entitySet, DbExpression refKeys, EntityType entityType)
            : base(cmdTree, DbExpressionKind.Ref) 
        {
            EntityUtil.CheckArgumentNull(entitySet, "entitySet");
            EntityUtil.CheckArgumentNull(refKeys, "refKeys");
 
            CommandTreeTypeHelper.CheckType(entityType);
            cmdTree.TypeHelper.CheckEntitySet(entitySet); 
 
            //
            // Verify that the specified return type of the Ref operation is actually in 
            // the same hierarchy as the Entity type of the specified Entity set.
            //
            if (!TypeSemantics.IsValidPolymorphicCast(entitySet.ElementType, entityType))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Ref_PolymorphicArgRequired);
            } 
 
            //
            // The Argument DbExpression must construct a set of values of the same types as the Key members of the Entity 
            // The names of the columns in the record type constructed by the Argument are not important, only that the
            // number of columns is the same as the number of Key members and that for each Key member the corresponding
            // column (based on order) is of a promotable type.
            // To enforce this the ArgumentLink ExpressionLink's ExpectedType is initialized to a record type based on the 
            // names and types of the Key members. Since the promotability check used in ExpressionLink will ignore the names
            // of the ExpectedType's columns, ExpressionLink will therefore enforce the required level of type correctness 
            // on the argument expression both here when it's value is first set (by calling ArgumentLink.InitializeValue) 
            // and subsequently when the value of the Argument property is set to a new value.
            // 
            // Set the expected type to be the record type created based on the Key members
            //
            TypeUsage keyType = CommandTreeTypeHelper.CreateResultType(TypeHelpers.CreateKeyRowType(entitySet.ElementType, cmdTree.MetadataWorkspace));
            this.ArgumentLink.SetExpectedType(keyType); 

            // 
            // Attempt to initialize the Argument to the specified DbExpression. 
            // If the type is not promotable to the record type set above (i.e. does
            // not have the same number of columns, with the type of each corresponding 
            // column promotable to the column type of the record's column, names ignored)
            // then the ExpressionLink will throw at this point.
            //
            this.ArgumentLink.InitializeValue(refKeys); 

            cmdTree.TrackContainer(entitySet.EntityContainer); 
 
            // Initialize the entitySet and result type properties.
            // The result type of the expression is Ref. 
            _entitySet = entitySet;
            this.ResultType = CommandTreeTypeHelper.CreateReferenceResultType(entityType);
        }
 
        /// 
        /// Gets the metadata for the entity set that contains the instance. 
        ///  
        public EntitySet EntitySet { get { return _entitySet; } }
 
        /// 
        /// 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 retrieval of a given entity using the specified Ref.
    /// 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Deref"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbDerefExpression : DbUnaryExpression 
    {
        internal DbDerefExpression(DbCommandTree cmdTree, DbExpression refExpr) 
            : base(cmdTree, DbExpressionKind.Deref, refExpr) 
        {
            // 
            // Ensure that the operand is actually of a reference type.
            //
            EntityType entityType;
            if(!TypeHelpers.TryGetRefEntityType(this.Argument.ResultType, out entityType)) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_DeRef_RefRequired, "Argument"); 
            } 

            // 
            // Result Type is the element type of the reference type
            //
            this.ResultType = CommandTreeTypeHelper.CreateResultType(entityType);
        } 

        ///  
        /// 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 'scan' of all elements of a given entity set. 
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    public sealed class DbScanExpression : DbExpression 
    {
        private EntitySetBase _targetSet;

        internal DbScanExpression(DbCommandTree cmdTree, EntitySetBase entitySet) 
            : base(cmdTree, DbExpressionKind.Scan)
        { 
            cmdTree.TypeHelper.CheckEntitySet(entitySet); 
            cmdTree.TrackContainer(entitySet.EntityContainer);
 
            _targetSet = entitySet;
            this.ResultType = CommandTreeTypeHelper.CreateCollectionResultType(entitySet.ElementType);
        }
 
        /// 
        /// Gets the metadata for the referenced entity or relationship set. 
        ///  
        public EntitySetBase Target { get { return _targetSet; } }
 
        /// 
        /// 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