DbExpressionBuilder.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Common / CommandTrees / ExpressionBuilder / DbExpressionBuilder.cs / 1599186 / DbExpressionBuilder.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System; 
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Common;
using System.Globalization; 
using System.IO;
using System.Linq; 
using System.Diagnostics; 
using System.Text;
using System.Text.RegularExpressions; 

using System.Data.Common.Utils;
using System.Data.Metadata.Edm;
using System.Data.Common.CommandTrees.Internal; 
using System.Data.Common.CommandTrees.ExpressionBuilder.Internal;
using System.Reflection; 
using System.Runtime.CompilerServices; 

namespace System.Data.Common.CommandTrees.ExpressionBuilder 
{
    /// 
    /// Provides an API to construct s and allows that API to be accessed as extension methods on the expression type itself.
    ///  
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
#if PUBLIC_DBEXPRESSIONBUILDER 
    public 
#endif
    static class DbExpressionBuilder 
    {
        #region Private Implementation

        private static readonly AliasGenerator _bindingAliases = new AliasGenerator("Var_", 0); 

        private static readonly DbNullExpression _binaryNull = Null(EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Binary)); 
        private static readonly DbNullExpression _boolNull = Null(EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Boolean)); 
        private static readonly DbNullExpression _byteNull = Null(EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Byte));
        private static readonly DbNullExpression _dateTimeNull = Null(EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(PrimitiveTypeKind.DateTime)); 
        private static readonly DbNullExpression _dateTimeOffsetNull = Null(EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(PrimitiveTypeKind.DateTimeOffset));
        private static readonly DbNullExpression _decimalNull = Null(EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Decimal));
        private static readonly DbNullExpression _doubleNull = Null(EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Double));
        private static readonly DbNullExpression _guidNull = Null(EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Guid)); 
        private static readonly DbNullExpression _int16Null = Null(EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Int16));
        private static readonly DbNullExpression _int32Null = Null(EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Int32)); 
        private static readonly DbNullExpression _int64Null = Null(EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Int64)); 
        private static readonly DbNullExpression _sbyteNull = Null(EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(PrimitiveTypeKind.SByte));
        private static readonly DbNullExpression _singleNull = Null(EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Single)); 
        private static readonly DbNullExpression _stringNull = Null(EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(PrimitiveTypeKind.String));
        private static readonly DbNullExpression _timeNull = Null(EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(PrimitiveTypeKind.Time));

        private static readonly DbConstantExpression _boolTrue = Constant(true); 
        private static readonly DbConstantExpression _boolFalse = Constant(false);
 
        #endregion 

        #region Helpers (not strictly Command Tree API) 

        public static KeyValuePair As(this DbExpression value, string alias)
        {
            return new KeyValuePair(alias, value); 
        }
 
        public static KeyValuePair As(this DbAggregate value, string alias) 
        {
            return new KeyValuePair(alias, value); 
        }

        #endregion
 
        #region Bindings - Expression and Group
 
        ///  
        /// Creates a new  that uses a generated variable name to bind the given expression
        ///  
        /// The expression to bind
        /// A new expression binding with the specified expression and a generated variable name
        ///  is null
        ///  does not have a collection result type 
        public static DbExpressionBinding Bind(this DbExpression input)
        { 
            return DbExpressionBuilder.BindAs(input, _bindingAliases.Next()); 
        }
 
        /// 
        /// Creates a new  that uses the specified variable name to bind the given expression
        /// 
        /// The expression to bind 
        /// The variable name that should be used for the binding
        /// A new expression binding with the specified expression and variable name 
        ///  or  is null 
        ///  does not have a collection result type
        public static DbExpressionBinding BindAs(this DbExpression input, string varName) 
        {
            TypeUsage elementType = ArgumentValidation.ValidateBindAs(input, varName);
            DbVariableReferenceExpression inputRef = new DbVariableReferenceExpression(elementType, varName);
            return new DbExpressionBinding(input, inputRef); 
        }
 
        ///  
        /// Creates a new group expression binding that uses generated variable and group variable names to bind the given expression
        ///  
        /// The expression to bind
        /// A new group expression binding with the specified expression and a generated variable name and group variable name
        ///  is null
        ///  does not have a collection result type 
        public static DbGroupExpressionBinding GroupBind(this DbExpression input)
        { 
            string alias = _bindingAliases.Next(); 
            return DbExpressionBuilder.GroupBindAs(input, alias, string.Format(CultureInfo.InvariantCulture, "Group{0}", alias));
        } 

        /// 
        /// Creates a new  that uses the specified variable name and group variable names to bind the given expression
        ///  
        /// The expression to bind
        /// The variable name that should be used for the binding 
        /// The variable name that should be used to refer to the group when the new group expression binding is used in a group-by expression 
        /// A new group expression binding with the specified expression, variable name and group variable name
        /// ,  or  is null 
        ///  does not have a collection result type
        public static DbGroupExpressionBinding GroupBindAs(this DbExpression input, string varName, string groupVarName)
        {
            TypeUsage elementType = ArgumentValidation.ValidateGroupBindAs(input, varName, groupVarName); 
            DbVariableReferenceExpression inputRef = new DbVariableReferenceExpression(elementType, varName);
            DbVariableReferenceExpression groupRef = new DbVariableReferenceExpression(elementType, groupVarName); 
            return new DbGroupExpressionBinding(input, inputRef, groupRef); 
        }
 
        #endregion

        #region Aggregates and SortClauses are required only for Binding-based method support - replaced by OrderBy[Descending]/ThenBy[Descending] and Aggregate[Distinct] methods in new API
 
        /// 
        /// Creates a new . 
        ///  
        /// The function that defines the aggregate operation.
        /// The argument over which the aggregate function should be calculated. 
        /// A new function aggregate with a reference to the given function and argument. The function aggregate's Distinct property will have the value false
        ///  or  is null
        /// 
        ///      is not an aggregate function or has more than one argument, or 
        ///     the result type of  is not equal or promotable to
        ///     the parameter type of  
        ///  
        public static DbFunctionAggregate Aggregate(this EdmFunction function, DbExpression argument)
        { 
            return CreateFunctionAggregate(function, argument, false);
        }

        ///  
        /// Creates a new  that is applied in a distinct fashion.
        ///  
        /// The function that defines the aggregate operation. 
        /// The argument over which the aggregate function should be calculated.
        /// A new function aggregate with a reference to the given function and argument. The function aggregate's Distinct property will have the value true 
        ///  or  is null
        /// 
        ///      is not an aggregate function or has more than one argument, or
        ///     the result type of  is not equal or promotable to 
        ///     the parameter type of 
        ///  
        public static DbFunctionAggregate AggregateDistinct(this EdmFunction function, DbExpression argument) 
        {
            return CreateFunctionAggregate(function, argument, true); 
        }

        private static DbFunctionAggregate CreateFunctionAggregate(EdmFunction function, DbExpression argument, bool isDistinct)
        { 
            EntityUtil.CheckArgumentNull(argument, "argument");
            DbExpressionList funcArgs = ArgumentValidation.ValidateFunctionAggregate(function, new[] { argument }); 
            TypeUsage resultType = function.ReturnParameter.TypeUsage; 
            return new DbFunctionAggregate(resultType, funcArgs, function, isDistinct);
        } 

        /// 
        /// Creates a new  over the specified argument
        ///  
        /// The argument over which to perform the nest operation
        /// A new group aggregate representing the elements of the group referenced by the given argument. 
        ///  is null 
        /*ENABLE_ELEMENT_SELECTOR(*/internal/*)*/ static DbGroupAggregate GroupAggregate(DbExpression argument)
        { 
            DbExpressionList arguments = ArgumentValidation.ValidateGroupAggregate(argument);
            TypeUsage resultType = TypeHelpers.CreateCollectionTypeUsage(argument.ResultType);
            return new DbGroupAggregate(resultType, arguments);
        } 

        ///  
        /// Creates a  with the specified inline Lambda function implementation and formal parameters. 
        /// 
        /// An expression that defines the logic of the Lambda function 
        /// 
        ///   A  collection that represents the formal parameters to the Lambda function.
        ///   These variables are valid for use in the  expression.
        ///  
        /// A new DbLambda that describes an inline Lambda function with the specified body and formal parameters
        ///  
        ///      is null or contains null, or  is null 
        /// .
        ///  
        ///      contains more than one element with the same variable name.
        /// 
        public static DbLambda Lambda(DbExpression body, IEnumerable variables)
        { 
            return CreateLambda(body, variables);
        } 
 
        /// 
        /// Creates a  with the specified inline Lambda function implementation and formal parameters. 
        /// 
        /// An expression that defines the logic of the Lambda function
        /// 
        ///   A  collection that represents the formal parameters to the Lambda function. 
        ///   These variables are valid for use in the  expression.
        ///  
        /// A new DbLambda that describes an inline Lambda function with the specified body and formal parameters 
        /// 
        ///      is null or contains null, or  is null 
        /// .
        /// 
        ///      contains more than one element with the same variable name.
        ///  
        public static DbLambda Lambda(DbExpression body, params DbVariableReferenceExpression[] variables)
        { 
            return CreateLambda(body, variables); 
        }
 
        private static DbLambda CreateLambda(DbExpression body, IEnumerable variables)
        {
            var validVars = ArgumentValidation.ValidateLambda(variables, body);
            return new DbLambda(validVars, body); 
        }
 
        ///  
        /// Creates a new  with an ascending sort order and default collation
        ///  
        /// The expression that defines the sort key
        /// A new sort clause with the given sort key and ascending sort order
        ///  is null
        ///  does not have an order-comparable result type 
        public static DbSortClause ToSortClause(this DbExpression key)
        { 
            ArgumentValidation.ValidateSortClause(key); 
            return new DbSortClause(key, true, String.Empty);
        } 

        /// 
        /// Creates a new  with a descending sort order and default collation
        ///  
        /// The expression that defines the sort key
        /// A new sort clause with the given sort key and descending sort order 
        ///  is null 
        ///  does not have an order-comparable result type
        public static DbSortClause ToSortClauseDescending(this DbExpression key) 
        {
            ArgumentValidation.ValidateSortClause(key);
            return new DbSortClause(key, false, String.Empty);
        } 

        ///  
        /// Creates a new  with an ascending sort order and the specified collation 
        /// 
        /// The expression that defines the sort key 
        /// The collation to sort under
        /// A new sort clause with the given sort key and collation, and ascending sort order
        ///  is null
        ///  is empty or contains only space characters 
        ///  does not have an order-comparable result type
        public static DbSortClause ToSortClause(this DbExpression key, string collation) 
        { 
            ArgumentValidation.ValidateSortClause(key, collation);
            return new DbSortClause(key, true, collation); 
        }

        /// 
        /// Creates a new  with a descending sort order and the specified collation 
        /// 
        /// The expression that defines the sort key 
        /// The collation to sort under 
        /// A new sort clause with the given sort key and collation, and descending sort order
        ///  is null 
        ///  is empty or contains only space characters
        ///  does not have an order-comparable result type
        public static DbSortClause ToSortClauseDescending(this DbExpression key, string collation)
        { 
            ArgumentValidation.ValidateSortClause(key, collation);
            return new DbSortClause(key, false, collation); 
        } 

        #endregion 

        #region Binding-based methods: All, Any, Cross|OuterApply, Cross|FullOuter|Inner|LeftOuterJoin, Filter, GroupBy, Project, Skip, Sort

        ///  
        /// Creates a new  that determines whether the given predicate holds for all elements of the input set.
        ///  
        /// An expression binding that specifies the input set. 
        /// An expression representing a predicate to evaluate for each member of the input set.
        /// A new DbQuantifierExpression that represents the All operation. 
        ///  or  is null
        /// 
        ///      does not have a Boolean result type.
        ///  
        public static DbQuantifierExpression All(this DbExpressionBinding input, DbExpression predicate)
        { 
            TypeUsage booleanResultType = ArgumentValidation.ValidateQuantifier(input, predicate); 
            return new DbQuantifierExpression(DbExpressionKind.All, booleanResultType, input, predicate);
        } 

        /// 
        /// Creates a new  that determines whether the given predicate holds for any element of the input set.
        ///  
        /// An expression binding that specifies the input set.
        /// An expression representing a predicate to evaluate for each member of the input set. 
        /// A new DbQuantifierExpression that represents the Any operation. 
        ///  or  is null
        ///  
        ///      does not have a Boolean result type.
        /// 
        public static DbQuantifierExpression Any(this DbExpressionBinding input, DbExpression predicate)
        { 
            TypeUsage booleanResultType = ArgumentValidation.ValidateQuantifier(input, predicate);
            return new DbQuantifierExpression(DbExpressionKind.Any, booleanResultType, input, predicate); 
        } 

        ///  
        /// Creates a new  that evaluates the given  expression once for each element of a given input set,
        /// producing a collection of rows with corresponding input and apply columns. Rows for which  evaluates to an empty set are not included.
        /// 
        /// An  that specifies the input set. 
        /// An  that specifies logic to evaluate once for each member of the input set.
        /// An new DbApplyExpression with the specified input and apply bindings and an  of CrossApply. 
        ///  or  is null 
        public static DbApplyExpression CrossApply(this DbExpressionBinding input, DbExpressionBinding apply)
        { 
            TypeUsage resultType = ArgumentValidation.ValidateApply(input, apply);
            return new DbApplyExpression(DbExpressionKind.CrossApply, resultType, input, apply);
        }
 
        /// 
        /// Creates a new  that evaluates the given  expression once for each element of a given input set, 
        /// producing a collection of rows with corresponding input and apply columns. Rows for which  evaluates to an empty set have an apply column value of null. 
        /// 
        /// An  that specifies the input set. 
        /// An  that specifies logic to evaluate once for each member of the input set.
        /// An new DbApplyExpression with the specified input and apply bindings and an  of OuterApply.
        ///  or  is null
        public static DbApplyExpression OuterApply(this DbExpressionBinding input, DbExpressionBinding apply) 
        {
            TypeUsage resultType = ArgumentValidation.ValidateApply(input, apply); 
            return new DbApplyExpression(DbExpressionKind.OuterApply, resultType, input, apply); 
        }
 
        /// 
        /// Creates a new  that unconditionally joins the sets specified by the list of input expression bindings.
        /// 
        /// A list of expression bindings that specifies the input sets. 
        /// A new DbCrossJoinExpression, with an  of CrossJoin, that represents the unconditional join of the input sets.
        ///  is null or contains null 
        ///  
        ///      contains fewer than 2 expression bindings.
        ///  
        public static DbCrossJoinExpression CrossJoin(IEnumerable inputs)
        {
            TypeUsage resultType;
            System.Collections.ObjectModel.ReadOnlyCollection validInputs = ArgumentValidation.ValidateCrossJoin(inputs, out resultType); 
            return new DbCrossJoinExpression(resultType, validInputs);
        } 
 
        /// 
        /// Creates a new  that joins the sets specified by the left and right 
        /// expression bindings, on the specified join condition, using InnerJoin as the .
        /// 
        /// An  that specifies the left set argument.
        /// An  that specifies the right set argument. 
        /// An expression that specifies the condition on which to join.
        ///  
        ///     A new DbJoinExpression, with an  of InnerJoin, that represents the inner join operation applied to the left and right 
        ///     input sets under the given join condition.
        ///  
        /// 
        ///     ,  or  is null.
        /// 
        ///  
        ///      does not have a Boolean result type.
        ///  
        public static DbJoinExpression InnerJoin(this DbExpressionBinding left, DbExpressionBinding right, DbExpression joinCondition) 
        {
            TypeUsage resultType = ArgumentValidation.ValidateJoin(left, right, joinCondition); 
            return new DbJoinExpression(DbExpressionKind.InnerJoin, resultType, left, right, joinCondition);
        }

        ///  
        /// Creates a new  that joins the sets specified by the left and right
        /// expression bindings, on the specified join condition, using LeftOuterJoin as the . 
        ///  
        /// An  that specifies the left set argument.
        /// An  that specifies the right set argument. 
        /// An expression that specifies the condition on which to join.
        /// 
        ///     A new DbJoinExpression, with an  of LeftOuterJoin, that represents the left outer join operation applied to the left and right
        ///     input sets under the given join condition. 
        /// 
        ///  
        ///     ,  or  is null. 
        /// 
        ///  
        ///      does not have a Boolean result type.
        /// 
        public static DbJoinExpression LeftOuterJoin(this DbExpressionBinding left, DbExpressionBinding right, DbExpression joinCondition)
        { 
            TypeUsage resultType = ArgumentValidation.ValidateJoin(left, right, joinCondition);
            return new DbJoinExpression(DbExpressionKind.LeftOuterJoin, resultType, left, right, joinCondition); 
        } 

        ///  
        /// Creates a new  that joins the sets specified by the left and right
        /// expression bindings, on the specified join condition, using FullOuterJoin as the .
        /// 
        /// An  that specifies the left set argument. 
        /// An  that specifies the right set argument.
        /// An expression that specifies the condition on which to join. 
        ///  
        ///     A new DbJoinExpression, with an  of FullOuterJoin, that represents the full outer join operation applied to the left and right
        ///     input sets under the given join condition. 
        /// 
        /// 
        ///     ,  or  is null.
        ///  
        /// 
        ///      does not have a Boolean result type. 
        ///  
        public static DbJoinExpression FullOuterJoin(this DbExpressionBinding left, DbExpressionBinding right, DbExpression joinCondition)
        { 
            TypeUsage resultType = ArgumentValidation.ValidateJoin(left, right, joinCondition);
            return new DbJoinExpression(DbExpressionKind.FullOuterJoin, resultType, left, right, joinCondition);
        }
 
        /// 
        /// Creates a new  that filters the elements in the given input set using the specified predicate. 
        ///  
        /// An expression binding that specifies the input set.
        /// An expression representing a predicate to evaluate for each member of the input set. 
        /// A new DbFilterExpression that produces the filtered set.
        ///  or  is null
        /// 
        ///      does not have a Boolean result type. 
        /// 
        public static DbFilterExpression Filter(this DbExpressionBinding input, DbExpression predicate) 
        { 
            TypeUsage resultType = ArgumentValidation.ValidateFilter(input, predicate);
            return new DbFilterExpression(resultType, input, predicate); 
        }

        /// 
        /// Creates a new  that groups the elements of the input set according to the specified group keys and applies the given aggregates. 
        /// 
        /// A  that specifies the input set. 
        /// A list of string-expression pairs that define the grouping columns. 
        /// A list of expressions that specify aggregates to apply.
        /// A new DbGroupByExpression with the specified input set, grouping keys and aggregates. 
        /// 
        ///     ,  or  is null,
        ///      contains a null key column name or expression, or
        ///      contains a null aggregate column name or aggregate. 
        /// 
        ///  
        ///     Both  and  are empty, 
        ///     or an invalid or duplicate column name was specified.
        ///  
        /// 
        ///     DbGroupByExpression allows either the list of keys or the list of aggregates to be empty, but not both.
        /// 
        public static DbGroupByExpression GroupBy(this DbGroupExpressionBinding input, IEnumerable> keys, IEnumerable> aggregates) 
        {
            DbExpressionList validKeys; 
            System.Collections.ObjectModel.ReadOnlyCollection validAggregates; 
            TypeUsage resultType = ArgumentValidation.ValidateGroupBy(input, keys, aggregates, out validKeys, out validAggregates);
            return new DbGroupByExpression(resultType, input, validKeys, validAggregates); 
        }

        /// 
        /// Creates a new  that projects the specified expression over the given input set. 
        /// 
        /// An expression binding that specifies the input set. 
        /// An expression to project over the set. 
        /// A new DbProjectExpression that represents the projection operation.
        ///  or  is null 
        public static DbProjectExpression Project(this DbExpressionBinding input, DbExpression projection)
        {
            TypeUsage resultType = ArgumentValidation.ValidateProject(input, projection);
            return new DbProjectExpression(resultType, input, projection); 
        }
 
        ///  
        /// Creates a new  that sorts the given input set by the given sort specifications before skipping the specified number of elements.
        ///  
        /// An expression binding that specifies the input set.
        /// A list of sort specifications that determine how the elements of the input set should be sorted.
        /// An expression the specifies how many elements of the ordered set to skip.
        /// A new DbSkipExpression that represents the skip operation. 
        /// 
        ///     ,  or  is null, 
        ///     or  contains null. 
        /// 
        ///  
        ///      is empty,
        ///     or  is not  or  or has a
        ///     result type that is not equal or promotable to a 64-bit integer type.
        ///  
        public static DbSkipExpression Skip(this DbExpressionBinding input, IEnumerable sortOrder, DbExpression count)
        { 
            System.Collections.ObjectModel.ReadOnlyCollection validSortOrder = ArgumentValidation.ValidateSkip(input, sortOrder, count); 
            return new DbSkipExpression(input.Expression.ResultType, input, validSortOrder, count);
        } 

        /// 
        /// Creates a new  that sorts the given input set by the specified sort specifications.
        ///  
        /// An expression binding that specifies the input set.
        /// A list of sort specifications that determine how the elements of the input set should be sorted. 
        /// A new DbSortExpression that represents the sort operation. 
        /// 
        ///      or  is null, 
        ///     or  contains null.
        /// 
        /// 
        ///      is empty. 
        /// 
        public static DbSortExpression Sort(this DbExpressionBinding input, IEnumerable sortOrder) 
        { 
            System.Collections.ObjectModel.ReadOnlyCollection validSortOrder = ArgumentValidation.ValidateSort(input, sortOrder);
            return new DbSortExpression(input.Expression.ResultType, input, validSortOrder); 
        }

        #endregion
 
        #region Leaf Expressions - Null, Constant, Parameter, Scan
 
#if DBEXPRESSIONBUILDER_NULLCONSTANTS 
        // Binary
        public static DbNullExpression NullBinary { get { return _binaryNull; } } 
        // Boolean
        public static DbNullExpression NullBoolean { get { return _boolNull; } }
        // Byte
        public static DbNullExpression NullByte { get { return _byteNull; } } 
        // DateTime
        public static DbNullExpression NullDateTime { get { return _dateTimeNull; } } 
        // DateTimeOffset 
        public static DbNullExpression NullDateTimeOffset { get { return _dateTimeOffsetNull; } }
        // Decimal 
        public static DbNullExpression NullDecimal { get { return _decimalNull; } }
        // Double
        public static DbNullExpression NullDouble { get { return _doubleNull; } }
        // Guid 
        public static DbNullExpression NullGuid { get { return _guidNull; } }
        // Int16 
        public static DbNullExpression NullInt16 { get { return _int16Null; } } 
        // Int32
        public static DbNullExpression NullInt32 { get { return _int32Null; } } 
        // Int64
        public static DbNullExpression NullInt64 { get { return _int64Null; } }
        // SByte
        public static DbNullExpression NullSByte { get { return _sbyteNull; } } 
        // Single
        public static DbNullExpression NullSingle { get { return _singleNull; } } 
        // String 
        public static DbNullExpression NullString { get { return _stringNull; } }
        // Time 
        public static DbNullExpression NullTime { get { return _timeNull; } }
#endif

        ///  
        /// Creates a new , which represents a typed null value.
        ///  
        /// The type of the null value. 
        /// An instance of DbNullExpression
        ///  is null 
        public static DbNullExpression Null(this TypeUsage nullType)
        {
            ArgumentValidation.ValidateNull(nullType);
            return new DbNullExpression(nullType); 
        }
 
        ///  
        /// Creates a  with the Boolean value true.
        ///  
        /// A DbConstantExpression with the Boolean value true.
        public static DbConstantExpression True { get { return _boolTrue; } }

        ///  
        /// Creates a  with the Boolean value false.
        ///  
        /// A DbConstantExpression with the Boolean value false. 
        public static DbConstantExpression False { get { return _boolFalse; } }
 
        /// 
        /// Creates a new  with the given constant value.
        /// 
        /// The constant value to represent. 
        /// A new DbConstantExpression with the given value.
        ///  is null 
        ///  is not an instance of a valid constant type 
        public static DbConstantExpression Constant(object value)
        { 
            TypeUsage constantType = ArgumentValidation.ValidateConstant(value);
            return new DbConstantExpression(constantType, value);
        }
 
        /// 
        /// Creates a new  of the specified primitive type with the given constant value. 
        ///  
        /// The type of the constant value.
        /// The constant value to represent. 
        /// A new DbConstantExpression with the given value and a result type of .
        ///  or  is null
        /// 
        ///      is not an instance of a valid constant type, 
        ///      does not represent a primitive type, or
        ///      is of a different primitive type than that represented by  
        ///  
        public static DbConstantExpression Constant(this TypeUsage constantType, object value)
        { 
            ArgumentValidation.ValidateConstant(constantType, value);
            return new DbConstantExpression(constantType, value);
        }
 
        /// 
        /// Creates a new  that references a parameter with the specified name and type. 
        ///  
        /// The type of the referenced parameter
        /// The name of the referenced parameter 
        /// 
        ///   A DbParameterReferenceExpression that represents a reference to a parameter with the specified name and type;
        ///   the result type of the expression will be the same as .
        ///  
        public static DbParameterReferenceExpression Parameter(this TypeUsage type, string name)
        { 
            ArgumentValidation.ValidateParameter(type, name); 
            return new DbParameterReferenceExpression(type, name);
        } 

        /// 
        /// Creates a new  that references a variable with the specified name and type.
        ///  
        /// The type of the referenced variable
        /// The name of the referenced variable 
        ///  
        ///   A DbVariableReferenceExpression that represents a reference to a variable with the specified name and type;
        ///   the result type of the expression will be the same as . 
        /// 
        public static DbVariableReferenceExpression Variable(this TypeUsage type, string name)
        {
            ArgumentValidation.ValidateVariable(type, name); 
            return new DbVariableReferenceExpression(type, name);
        } 
 
        /// 
        /// Creates a new  that references the specified entity or relationship set. 
        /// 
        /// Metadata for the entity or relationship set to reference.
        /// A new DbScanExpression based on the specified entity or relationship set.
        ///  is null 
        public static DbScanExpression Scan(this EntitySetBase targetSet)
        { 
            TypeUsage resultType = ArgumentValidation.ValidateScan(targetSet); 
            return new DbScanExpression(resultType, targetSet);
        } 

        #endregion

        #region Boolean Operators - And, Or, Not 

        ///  
        /// Creates an  that performs the logical And of the left and right arguments. 
        /// 
        /// A Boolean expression that specifies the left argument. 
        /// A Boolean expression that specifies the right argument.
        /// A new DbAndExpression with the specified arguments.
        ///  or  is null
        ///  
        ///      or  does not have a Boolean result type.
        ///  
        public static DbAndExpression And(this DbExpression left, DbExpression right) 
        {
            TypeUsage resultType = ArgumentValidation.ValidateAnd(left, right); 
            return new DbAndExpression(resultType, left, right);
        }

        ///  
        /// Creates an  that performs the logical Or of the left and right arguments.
        ///  
        /// A Boolean expression that specifies the left argument. 
        /// A Boolean expression that specifies the right argument.
        /// A new DbOrExpression with the specified arguments. 
        ///  or  is null
        /// 
        ///      or  does not have a Boolean result type.
        ///  
        public static DbOrExpression Or(this DbExpression left, DbExpression right)
        { 
            TypeUsage resultType = ArgumentValidation.ValidateOr(left, right); 
            return new DbOrExpression(resultType, left, right);
        } 

        /// 
        /// Creates a  that performs the logical negation of the given argument.
        ///  
        /// A Boolean expression that specifies the argument.
        /// A new DbNotExpression with the specified argument. 
        ///  is null 
        /// 
        ///      does not have a Boolean result type. 
        /// 
        public static DbNotExpression Not(this DbExpression argument)
        {
            TypeUsage resultType = ArgumentValidation.ValidateNot(argument); 
            return new DbNotExpression(resultType, argument);
        } 
 
        #endregion
 
        #region Arithmetic Operators - Divide, Minus, Modulo, Multiply, Plus, UnaryMinus

        private static DbArithmeticExpression CreateArithmetic(DbExpressionKind kind, DbExpression left, DbExpression right)
        { 
            TypeUsage numericResultType;
            DbExpressionList arguments = ArgumentValidation.ValidateArithmetic(left, right, out numericResultType); 
            return new DbArithmeticExpression(kind, numericResultType, arguments); 
        }
 
        /// 
        /// Creates a new  that divides the left argument by the right argument.
        /// 
        /// An expression that specifies the left argument. 
        /// An expression that specifies the right argument.
        /// A new DbArithmeticExpression representing the division operation. 
        ///  or  is null 
        /// 
        ///     No common numeric result type exists between  and . 
        /// 
        public static DbArithmeticExpression Divide(this DbExpression left, DbExpression right)
        {
            return CreateArithmetic(DbExpressionKind.Divide, left, right); 
        }
 
        ///  
        /// Creates a new  that subtracts the right argument from the left argument.
        ///  
        /// An expression that specifies the left argument.
        /// An expression that specifies the right argument.
        /// A new DbArithmeticExpression representing the subtraction operation.
        ///  or  is null 
        /// 
        ///     No common numeric result type exists between  and . 
        ///  
        public static DbArithmeticExpression Minus(this DbExpression left, DbExpression right)
        { 
            return CreateArithmetic(DbExpressionKind.Minus, left, right);
        }

        ///  
        /// Creates a new  that computes the remainder of the left argument divided by the right argument.
        ///  
        /// An expression that specifies the left argument. 
        /// An expression that specifies the right argument.
        /// A new DbArithmeticExpression representing the modulo operation. 
        ///  or  is null
        /// 
        ///     No common numeric result type exists between  and .
        ///  
        public static DbArithmeticExpression Modulo(this DbExpression left, DbExpression right)
        { 
            return CreateArithmetic(DbExpressionKind.Modulo, left, right); 
        }
 
        /// 
        /// Creates a new  that multiplies the left argument by the right argument.
        /// 
        /// An expression that specifies the left argument. 
        /// An expression that specifies the right argument.
        /// A new DbArithmeticExpression representing the multiplication operation. 
        ///  or  is null 
        /// 
        ///     No common numeric result type exists between  and . 
        /// 
        public static DbArithmeticExpression Multiply(this DbExpression left, DbExpression right)
        {
            return CreateArithmetic(DbExpressionKind.Multiply, left, right); 
        }
 
        ///  
        /// Creates a new  that adds the left argument to the right argument.
        ///  
        /// An expression that specifies the left argument.
        /// An expression that specifies the right argument.
        /// A new DbArithmeticExpression representing the addition operation.
        ///  or  is null 
        /// 
        ///     No common numeric result type exists between  and . 
        ///  
        public static DbArithmeticExpression Plus(this DbExpression left, DbExpression right)
        { 
            return CreateArithmetic(DbExpressionKind.Plus, left, right);
        }

        ///  
        /// Creates a new  that negates the value of the argument.
        ///  
        /// An expression that specifies the argument. 
        /// A new DbArithmeticExpression representing the negation operation.
        ///  is null 
        /// 
        ///     No numeric result type exists for .
        /// 
        public static DbArithmeticExpression UnaryMinus(this DbExpression argument) 
        {
            TypeUsage resultType; 
            DbExpressionList args = ArgumentValidation.ValidateArithmetic(argument, out resultType); 
            return new DbArithmeticExpression(DbExpressionKind.UnaryMinus, resultType, args);
        } 

        /// 
        /// Creates a new  that negates the value of the argument.
        ///  
        /// An expression that specifies the argument.
        /// A new DbArithmeticExpression representing the negation operation. 
        ///  is null 
        /// 
        ///     No numeric result type exists for . 
        /// 
        public static DbArithmeticExpression Negate(this DbExpression argument)
        {
            return DbExpressionBuilder.UnaryMinus(argument); 
        }
 
        #endregion 

        #region Comparison Operators - Equal, NotEqual, GreaterThan, LessThan, GreaterThanEqual, LessThanEqual, IsNull, Like 

        private static DbComparisonExpression CreateComparison(DbExpressionKind kind, DbExpression left, DbExpression right)
        {
            TypeUsage resultType = ArgumentValidation.ValidateComparison(kind, left, right); 
            return new DbComparisonExpression(kind, resultType, left, right);
        } 
 
        /// 
        /// Creates a new  that compares the left and right arguments for equality. 
        /// 
        /// An expression that specifies the left argument.
        /// An expression that specifies the right argument.
        /// A new DbComparisonExpression representing the equality comparison. 
        ///  or  is null
        ///  
        ///     No common equality-comparable result type exists between  and . 
        /// 
        public static DbComparisonExpression Equal(this DbExpression left, DbExpression right) 
        {
            return DbExpressionBuilder.CreateComparison(DbExpressionKind.Equals, left, right);
        }
 
        /// 
        /// Creates a new  that compares the left and right arguments for inequality. 
        ///  
        /// An expression that specifies the left argument.
        /// An expression that specifies the right argument. 
        /// A new DbComparisonExpression representing the inequality comparison.
        ///  or  is null
        /// 
        ///     No common equality-comparable result type exists between  and . 
        /// 
        public static DbComparisonExpression NotEqual(this DbExpression left, DbExpression right) 
        { 
            return DbExpressionBuilder.CreateComparison(DbExpressionKind.NotEquals, left, right);
        } 

        /// 
        /// Creates a new  that determines whether the left argument is greater than the right argument.
        ///  
        /// An expression that specifies the left argument.
        /// An expression that specifies the right argument. 
        /// A new DbComparisonExpression representing the greater-than comparison. 
        ///  or  is null
        ///  
        ///     No common order-comparable result type exists between  and .
        /// 
        public static DbComparisonExpression GreaterThan(this DbExpression left, DbExpression right)
        { 
            return DbExpressionBuilder.CreateComparison(DbExpressionKind.GreaterThan, left, right);
        } 
 
        /// 
        /// Creates a new  that determines whether the left argument is less than the right argument. 
        /// 
        /// An expression that specifies the left argument.
        /// An expression that specifies the right argument.
        /// A new DbComparisonExpression representing the less-than comparison. 
        ///  or  is null
        ///  
        ///     No common order-comparable result type exists between  and . 
        /// 
        public static DbComparisonExpression LessThan(this DbExpression left, DbExpression right) 
        {
            return DbExpressionBuilder.CreateComparison(DbExpressionKind.LessThan, left, right);
        }
 
        /// 
        /// Creates a new  that determines whether the left argument is greater than or equal to the right argument. 
        ///  
        /// An expression that specifies the left argument.
        /// An expression that specifies the right argument. 
        /// A new DbComparisonExpression representing the greater-than-or-equal-to comparison.
        ///  or  is null
        /// 
        ///     No common result type that is both equality- and order-comparable exists between  and . 
        /// 
        public static DbComparisonExpression GreaterThanOrEqual(this DbExpression left, DbExpression right) 
        { 
            return DbExpressionBuilder.CreateComparison(DbExpressionKind.GreaterThanOrEquals, left, right);
        } 

        /// 
        /// Creates a new  that determines whether the left argument is less than or equal to the right argument.
        ///  
        /// An expression that specifies the left argument.
        /// An expression that specifies the right argument. 
        /// A new DbComparisonExpression representing the less-than-or-equal-to comparison. 
        ///  or  is null
        ///  
        ///     No common result type that is both equality- and order-comparable exists between  and .
        /// 
        public static DbComparisonExpression LessThanOrEqual(this DbExpression left, DbExpression right)
        { 
            return DbExpressionBuilder.CreateComparison(DbExpressionKind.LessThanOrEquals, left, right);
        } 
 
        /// 
        /// Creates a new  that determines whether the specified argument is null. 
        /// 
        /// An expression that specifies the argument.
        /// A new DbIsNullExpression with the specified argument.
        ///  is null 
        ///  has a collection result type.
        public static DbIsNullExpression IsNull(this DbExpression argument) 
        { 
            TypeUsage resultType = ArgumentValidation.ValidateIsNull(argument);
            return new DbIsNullExpression(resultType, argument, false); 
        }

        /// 
        /// Creates a new  that compares the specified input string to the given pattern. 
        /// 
        /// An expression that specifies the input string. 
        /// An expression that specifies the pattern string. 
        /// A new DbLikeExpression with the specified input, pattern and a null escape.
        ///  or  is null 
        ///  or  does not have a string result type.
        public static DbLikeExpression Like(this DbExpression argument, DbExpression pattern)
        {
            TypeUsage resultType = ArgumentValidation.ValidateLike(argument, pattern); 
            DbExpression escape = DbExpressionBuilder.Null(pattern.ResultType);
            return new DbLikeExpression(resultType, argument, pattern, escape); 
        } 

        ///  
        /// Creates a new  that compares the specified input string to the given pattern using the optional escape.
        /// 
        /// An expression that specifies the input string.
        /// An expression that specifies the pattern string. 
        /// An optional expression that specifies the escape string.
        /// A new DbLikeExpression with the specified input, pattern and escape. 
        /// ,  or  is null 
        /// ,  or  does not have a string result type.
        public static DbLikeExpression Like(this DbExpression argument, DbExpression pattern, DbExpression escape) 
        {
            TypeUsage resultType = ArgumentValidation.ValidateLike(argument, pattern, escape);
            return new DbLikeExpression(resultType, argument, pattern, escape);
        } 

        #endregion 
 
        #region Type Operators - Cast, Treat, OfType, OfTypeOnly, IsOf, IsOfOnly
 
        /// 
        /// Creates a new  that applies a cast operation to a polymorphic argument.
        /// 
        /// The argument to which the cast should be applied. 
        /// Type metadata that specifies the type to cast to.
        /// A new DbCastExpression with the specified argument and target type. 
        ///  or  is null 
        /// The specified cast is not valid.
        public static DbCastExpression CastTo(this DbExpression argument, TypeUsage toType) 
        {
            ArgumentValidation.ValidateCastTo(argument, toType);
            return new DbCastExpression(toType, argument);
        } 

        ///  
        /// Creates a new . 
        /// 
        /// An expression that specifies the instance. 
        /// Type metadata for the treat-as type.
        /// A new DbTreatExpression with the specified argument and type.
        ///  or  is null
        ///  is not in the same type hierarchy as the result type of . 
        /// 
        ///  
        ///     DbTreatExpression requires that  has a polymorphic result type, 
        ///     and that  is a type from the same type hierarchy as that result type.
        ///  
        public static DbTreatExpression TreatAs(this DbExpression argument, TypeUsage treatType)
        {
            ArgumentValidation.ValidateTreatAs(argument, treatType);
            return new DbTreatExpression(treatType, argument); 
        }
 
        ///  
        /// Creates a new  that produces a set consisting of the elements of the given input set that are of the specified type.
        ///  
        /// A  that specifies the input set.
        /// Type metadata for the type that elements of the input set must have to be included in the resulting set.
        /// A new DbOfTypeExpression with the specified set argument and type, and an ExpressionKind of .
        ///  or  is null 
        /// 
        ///      does not have a collection result type, or 
        ///      is not a type in the same type hierarchy as the element type of the 
        ///     collection result type of .
        ///  
        /// 
        ///     DbOfTypeExpression requires that  has a collection result type with
        ///     a polymorphic element type, and that  is a type from the same type hierarchy as that element type.
        ///  
        public static DbOfTypeExpression OfType(this DbExpression argument, TypeUsage type)
        { 
            TypeUsage collectionOfTypeResultType = ArgumentValidation.ValidateOfType(argument, type); 
            return new DbOfTypeExpression(DbExpressionKind.OfType, collectionOfTypeResultType, argument, type);
        } 

        /// 
        /// Creates a new  that produces a set consisting of the elements of the given input set that are of exactly the specified type.
        ///  
        /// An  that specifies the input set.
        /// Type metadata for the type that elements of the input set must match exactly to be included in the resulting set. 
        /// A new DbOfTypeExpression with the specified set argument and type, and an ExpressionKind of . 
        ///  or  is null
        ///  
        ///      does not have a collection result type, or
        ///      is not a type in the same type hierarchy as the element type of the
        ///     collection result type of .
        ///  
        /// 
        ///     DbOfTypeExpression requires that  has a collection result type with 
        ///     a polymorphic element type, and that  is a type from the same type hierarchy as that element type. 
        /// 
        public static DbOfTypeExpression OfTypeOnly(this DbExpression argument, TypeUsage type) 
        {
            TypeUsage collectionOfTypeResultType = ArgumentValidation.ValidateOfType(argument, type);
            return new DbOfTypeExpression(DbExpressionKind.OfTypeOnly, collectionOfTypeResultType, argument, type);
        } 

        ///  
        /// Creates a new  that determines whether the given argument is of the specified type or a subtype. 
        /// 
        /// An expression that specifies the instance. 
        /// Type metadata that specifies the type that the instance's result type should be compared to.
        /// A new DbIsOfExpression with the specified instance and type and DbExpressionKind IsOf.
        ///  or  is null
        ///  
        ///      is not in the same type hierarchy as the result type of .
        ///  
        ///  
        ///     DbIsOfExpression requires that  has a polymorphic result type,
        ///     and that  is a type from the same type hierarchy as that result type. 
        /// 
        public static DbIsOfExpression IsOf(this DbExpression argument, TypeUsage type)
        {
            TypeUsage booleanResultType = ArgumentValidation.ValidateIsOf(argument, type); 
            return new DbIsOfExpression(DbExpressionKind.IsOf, booleanResultType, argument, type);
        } 
 
        /// 
        /// Creates a new  expression that determines whether the given argument is of the specified type, and only that type (not a subtype). 
        /// 
        /// An expression that specifies the instance.
        /// Type metadata that specifies the type that the instance's result type should be compared to.
        /// A new DbIsOfExpression with the specified instance and type and DbExpressionKind IsOfOnly. 
        ///  or  is null
        ///  
        ///      is not in the same type hierarchy as the result type of . 
        /// 
        ///  
        ///     DbIsOfExpression requires that  has a polymorphic result type,
        ///     and that  is a type from the same type hierarchy as that result type.
        /// 
        public static DbIsOfExpression IsOfOnly(this DbExpression argument, TypeUsage type) 
        {
            TypeUsage booleanResultType = ArgumentValidation.ValidateIsOf(argument, type); 
            return new DbIsOfExpression(DbExpressionKind.IsOfOnly, booleanResultType, argument, type); 
        }
 
        #endregion

        #region Ref Operators - Deref, EntityRef, Ref, RefKey, RelationshipNavigation
 
        /// 
        /// Creates a new  that retrieves a specific Entity given a reference expression 
        ///  
        /// An  that provides the reference. This expression must have a reference Type
        /// A new DbDerefExpression that retrieves the specified Entity 
        ///  is null
        ///  does not have a reference result type.
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Deref")]
        public static DbDerefExpression Deref(this DbExpression argument) 
        {
            TypeUsage entityResultType = ArgumentValidation.ValidateDeref(argument); 
            return new DbDerefExpression(entityResultType, argument); 
        }
 
        /// 
        /// Creates a new  that retrieves the ref of the specifed entity in structural form.
        /// 
        /// The expression that provides the entity. This expression must have an entity result type. 
        /// A new DbEntityRefExpression that retrieves a reference to the specified entity.
        ///  is null 
        ///  does not have an entity result type. 
        public static DbEntityRefExpression GetEntityRef(this DbExpression argument)
        { 
            TypeUsage refResultType = ArgumentValidation.ValidateGetEntityRef(argument);
            return new DbEntityRefExpression(refResultType, argument);
        }
 
        /// 
        /// Creates a new  that encodes a reference to a specific entity based on key values. 
        ///  
        /// The entity set in which the referenced element resides.
        /// A collection of s that provide the key values. These expressions must match (in number, type, and order) the key properties of the referenced entity type. 
        /// A new DbRefExpression that references the element with the specified key values in the given entity set.
        ///  is null, or  is null or contains null.
        /// 
        ///     The count of  does not match the count of key members declared by the 's element type, 
        ///     or  contains an expression with a result type that is not compatible with the type of the corresponding key member.
        ///  
        public static DbRefExpression CreateRef(this EntitySet entitySet, IEnumerable keyValues) 
        {
            return CreateRefExpression(entitySet, keyValues); 
        }

        /// 
        /// Creates a new  that encodes a reference to a specific entity based on key values. 
        /// 
        /// The entity set in which the referenced element resides. 
        /// A collection of s that provide the key values. These expressions must match (in number, type, and order) the key properties of the referenced entity type. 
        /// A new DbRefExpression that references the element with the specified key values in the given entity set.
        ///  is null, or  is null or contains null. 
        /// 
        ///     The count of  does not match the count of key members declared by the 's element type,
        ///     or  contains an expression with a result type that is not compatible with the type of the corresponding key member.
        ///  
        public static DbRefExpression CreateRef(this EntitySet entitySet, params DbExpression[] keyValues)
        { 
            return CreateRefExpression(entitySet, keyValues); 
        }
 
        /// 
        /// Creates a new  that encodes a reference to a specific entity of a given type based on key values.
        /// 
        /// The entity set in which the referenced element resides. 
        /// The specific type of the referenced entity. This must be an entity type from the same hierarchy as the entity set's element type.
        /// A collection of s that provide the key values. These expressions must match (in number, type, and order) the key properties of the referenced entity type. 
        /// A new DbRefExpression that references the element with the specified key values in the given entity set. 
        ///  or  is null, or  is null or contains null.
        ///  is not from the same type hierarchy (a subtype, supertype, or the same type) as 's element type. 
        /// 
        ///     The count of  does not match the count of key members declared by the 's element type,
        ///     or  contains an expression with a result type that is not compatible with the type of the corresponding key member.
        ///  
        public static DbRefExpression CreateRef(this EntitySet entitySet, EntityType entityType, IEnumerable keyValues)
        { 
            return CreateRefExpression(entitySet, entityType, keyValues); 
        }
 
        /// 
        /// Creates a new  that encodes a reference to a specific entity of a given type based on key values.
        /// 
        /// The entity set in which the referenced element resides. 
        /// The specific type of the referenced entity. This must be an entity type from the same hierarchy as the entity set's element type.
        /// A collection of s that provide the key values. These expressions must match (in number, type, and order) the key properties of the referenced entity type. 
        /// A new DbRefExpression that references the element with the specified key values in the given entity set. 
        ///  or  is null, or  is null or contains null.
        ///  is not from the same type hierarchy (a subtype, supertype, or the same type) as 's element type. 
        /// 
        ///     The count of  does not match the count of key members declared by the 's element type,
        ///     or  contains an expression with a result type that is not compatible with the type of the corresponding key member.
        ///  
        public static DbRefExpression CreateRef(this EntitySet entitySet, EntityType entityType, params DbExpression[] keyValues)
        { 
            return CreateRefExpression(entitySet, entityType, keyValues); 
        }
 
        private static DbRefExpression CreateRefExpression(EntitySet entitySet, IEnumerable keyValues)
        {
            DbExpression keyConstructor;
            TypeUsage refResultType = ArgumentValidation.ValidateCreateRef(entitySet, keyValues, out keyConstructor); 
            return new DbRefExpression(refResultType, entitySet, keyConstructor);
        } 
 
        private static DbRefExpression CreateRefExpression(EntitySet entitySet, EntityType entityType, IEnumerable keyValues)
        { 
            DbExpression keyConstructor;
            TypeUsage refResultType = ArgumentValidation.ValidateCreateRef(entitySet, entityType, keyValues, out keyConstructor);
            return new DbRefExpression(refResultType, entitySet, keyConstructor);
        } 

        ///  
        /// Creates a new  that encodes a reference to a specific Entity based on key values. 
        /// 
        /// The Entity set in which the referenced element resides. 
        /// A  that constructs a record with columns that match (in number, type, and order) the Key properties of the referenced Entity type.
        /// A new DbRefExpression that references the element with the specified key values in the given Entity set.
        ///  or  is null
        ///  
        ///      does not have a record result type that matches the key properties of the referenced entity set's entity type.
        ///  
        ///  
        ///      should be an expression that specifies the key values that identify the referenced entity within the given entity set.
        ///     The result type of  should contain a corresponding column for each key property defined by 's entity type. 
        /// 
        public static DbRefExpression RefFromKey(this EntitySet entitySet, DbExpression keyRow)
        {
            TypeUsage refResultType = ArgumentValidation.ValidateRefFromKey(entitySet, keyRow); 
            return new DbRefExpression(refResultType, entitySet, keyRow);
        } 
 
        /// 
        /// Creates a new  that encodes a reference to a specific Entity based on key values. 
        /// 
        /// The Entity set in which the referenced element resides.
        /// A  that constructs a record with columns that match (in number, type, and order) the Key properties of the referenced Entity type.
        /// The type of the Entity that the reference should refer to. 
        /// A new DbRefExpression that references the element with the specified key values in the given Entity set.
        /// ,  or  is null 
        ///  
        ///      is not in the same type hierarchy as the entity set's entity type, or  does not have a
        ///     record result type that matches the key properties of the referenced entity set's entity type. 
        /// 
        /// 
        ///      should be an expression that specifies the key values that identify the referenced entity within the given entity set.
        ///     The result type of  should contain a corresponding column for each key property defined by 's entity type. 
        /// 
        public static DbRefExpression RefFromKey(this EntitySet entitySet, DbExpression keyRow, EntityType entityType) 
        { 
            TypeUsage refResultType = ArgumentValidation.ValidateRefFromKey(entitySet, keyRow, entityType);
            return new DbRefExpression(refResultType, entitySet, keyRow); 
        }

        /// 
        /// Creates a new  that retrieves the key values of the specifed reference in structural form. 
        /// 
        /// The expression that provides the reference. This expression must have a reference Type with an Entity element type. 
        /// A new DbRefKeyExpression that retrieves the key values of the specified reference. 
        ///  is null
        ///  does not have a reference result type. 
        public static DbRefKeyExpression GetRefKey(this DbExpression argument)
        {
            TypeUsage rowResultType = ArgumentValidation.ValidateGetRefKey(argument);
            return new DbRefKeyExpression(rowResultType, argument); 
        }
 
        ///  
        /// Creates a new  representing the navigation of a composition or association relationship.
        ///  
        /// An expression the specifies the instance from which naviagtion should occur
        /// Metadata for the property that represents the end of the relationship from which navigation should occur
        /// Metadata for the property that represents the end of the relationship to which navigation should occur
        /// A new DbRelationshipNavigationExpression representing the navigation of the specified from and to relation ends of the specified relation type from the specified navigation source instance 
        /// ,  or  is null
        ///  
        ///      and  are not declared by the same relationship type, or 
        ///      has a result type that is not compatible with the property type of .
        ///  
        /// 
        ///      requires that navigation always occur from a reference, and so  must always have a reference result type.
        /// 
        public static DbRelationshipNavigationExpression Navigate(this DbExpression navigateFrom, RelationshipEndMember fromEnd, RelationshipEndMember toEnd) 
        {
            RelationshipType relType; 
            TypeUsage resultType = ArgumentValidation.ValidateNavigate(navigateFrom, fromEnd, toEnd, out relType); 
            return new DbRelationshipNavigationExpression(resultType, relType, fromEnd, toEnd, navigateFrom);
        } 

        /// 
        /// Creates a new  representing the navigation of a composition or association relationship.
        ///  
        /// Metadata for the relation type that represents the relationship
        /// The name of the property of the relation type that represents the end of the relationship from which navigation should occur 
        /// The name of the property of the relation type that represents the end of the relationship to which navigation should occur 
        /// An expression the specifies the instance from which naviagtion should occur
        /// A new DbRelationshipNavigationExpression representing the navigation of the specified from and to relation ends of the specified relation type from the specified navigation source instance 
        /// 
        ///     , ,  or  is null.
        /// 
        ///  
        ///      is not associated with this command tree's metadata workspace or  is associated with a different command tree,
        ///     or  does not declare a relation end property with name  or , 
        ///     or  has a result type that is not compatible with the property type of the relation end property with name . 
        /// 
        ///  
        ///      requires that navigation always occur from a reference, and so  must always have a reference result type.
        /// 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        public static DbRelationshipNavigationExpression Navigate(this RelationshipType type, string fromEndName, string toEndName, DbExpression navigateFrom) 
        {
            RelationshipEndMember fromEnd; 
            RelationshipEndMember toEnd; 
            TypeUsage resultType = ArgumentValidation.ValidateNavigate(navigateFrom, type, fromEndName, toEndName, out fromEnd, out toEnd);
            return new DbRelationshipNavigationExpression(resultType, type, fromEnd, toEnd, navigateFrom); 
        }

        #endregion
 
        #region Unary and Binary Set Operators - Distinct, Element, IsEmpty, Except, Intersect, UnionAll, Limit
 
        ///  
        /// Creates a new  that removes duplicates from the given set argument.
        ///  
        /// An expression that defines the set over which to perfom the distinct operation.
        /// A new DbDistinctExpression that represents the distinct operation applied to the specified set argument.
        ///  is null
        ///  does not have a collection result type. 
        public static DbDistinctExpression Distinct(this DbExpression argument)
        { 
            TypeUsage resultType = ArgumentValidation.ValidateDistinct(argument); 
            return new DbDistinctExpression(resultType, argument);
        } 

        /// 
        /// Creates a new  that converts a single-member set into a singleton.
        ///  
        /// An expression that specifies the input set.
        /// A DbElementExpression that represents the conversion of the single-member set argument to a singleton. 
        ///  is null 
        ///  does not have a collection result type.
        public static DbElementExpression Element(this DbExpression argument) 
        {
            TypeUsage resultType = ArgumentValidation.ValidateElement(argument);
            return new DbElementExpression(resultType, argument);
        } 

        ///  
        /// Creates a new  that determines whether the specified set argument is an empty set. 
        /// 
        /// An expression that specifies the input set 
        /// A new DbIsEmptyExpression with the specified argument.
        ///  is null
        ///  does not have a collection result type.
        public static DbIsEmptyExpression IsEmpty(this DbExpression argument) 
        {
            TypeUsage booleanResultType = ArgumentValidation.ValidateIsEmpty(argument); 
            return new DbIsEmptyExpression(booleanResultType, argument); 
        }
 
        /// 
        /// Creates a new  that computes the subtraction of the right set argument from the left set argument.
        /// 
        /// An expression that defines the left set argument. 
        /// An expression that defines the right set argument.
        /// A new DbExceptExpression that represents the difference of the left argument from the right argument. 
        ///  or  is null 
        /// No common collection result type exists between  and .
        public static DbExceptExpression Except(this DbExpression left, DbExpression right) 
        {
            TypeUsage resultType = ArgumentValidation.ValidateExcept(left, right);
            return new DbExceptExpression(resultType, left, right);
        } 

        ///  
        /// Creates a new  that computes the intersection of the left and right set arguments. 
        /// 
        /// An expression that defines the left set argument. 
        /// An expression that defines the right set argument.
        /// A new DbIntersectExpression that represents the intersection of the left and right arguments.
        ///  or  is null
        /// No common collection result type exists between  and . 
        public static DbIntersectExpression Intersect(this DbExpression left, DbExpression right)
        { 
            TypeUsage resultType = ArgumentValidation.ValidateIntersect(left, right); 
            return new DbIntersectExpression(resultType, left, right);
        } 

        /// 
        /// Creates a new  that computes the union of the left and right set arguments and does not remove duplicates.
        ///  
        /// An expression that defines the left set argument.
        /// An expression that defines the right set argument. 
        /// A new DbUnionAllExpression that union, including duplicates, of the the left and right arguments. 
        ///  or  is null
        /// No common collection result type exists between  and . 
        public static DbUnionAllExpression UnionAll(this DbExpression left, DbExpression right)
        {
            TypeUsage resultType = ArgumentValidation.ValidateUnionAll(left, right);
            return new DbUnionAllExpression(resultType, left, right); 
        }
 
        ///  
        /// Creates a new  that restricts the number of elements in the Argument collection to the specified count Limit value.
        /// Tied results are not included in the output. 
        /// 
        /// An expression that specifies the input collection.
        /// An expression that specifies the limit value.
        /// A new DbLimitExpression with the specified argument and count limit values that does not include tied results. 
        ///  or  is null
        ///  
        ///      does not have a collection result type, 
        ///     or  does not have a result type that is equal or promotable to a 64-bit integer type.
        ///  
        public static DbLimitExpression Limit(this DbExpression argument, DbExpression count)
        {
            TypeUsage resultType = ArgumentValidation.ValidateLimit(argument, count);
            return new DbLimitExpression(resultType, argument, count, false); 
        }
 
        #endregion 

        #region General Operators - Case, Function, NewInstance, Property 

        /// 
        /// Creates a new .
        ///  
        /// A list of expressions that provide the conditional for of each case.
        /// A list of expressions that provide the result of each case. 
        /// An expression that defines the result when no case is matched. 
        /// A new DbCaseExpression with the specified cases and default result.
        ///  
        ///      or  is null or contains null,
        ///     or  is null.
        /// 
        ///  
        ///      or  is empty or  contains an expression with a non-Boolean result type, or
        ///     No common result type exists for all expressions in  and . 
        ///  
        public static DbCaseExpression Case(IEnumerable whenExpressions, IEnumerable thenExpressions, DbExpression elseExpression)
        { 
            DbExpressionList validWhens;
            DbExpressionList validThens;
            TypeUsage resultType = ArgumentValidation.ValidateCase(whenExpressions, thenExpressions, elseExpression, out validWhens, out validThens);
            return new DbCaseExpression(resultType, validWhens, validThens, elseExpression); 
        }
 
        ///  
        /// Creates a new  representing the invocation of the specified function with the given arguments.
        ///  
        /// Metadata for the function to invoke.
        /// A list of expressions that provide the arguments to the function.
        /// A new DbFunctionExpression representing the function invocation.
        ///  
        ///      is null, or  is null or contains null.
        ///  
        ///  
        ///     The count of  does not equal the number of parameters declared by ,
        ///     or  contains an expression that has a result type that is not equal or promotable 
        ///     to the corresponding function parameter type.
        /// 
        public static DbFunctionExpression Invoke(this EdmFunction function, IEnumerable arguments)
        { 
            return InvokeFunction(function, arguments);
        } 
 
        /// 
        /// Creates a new  representing the invocation of the specified function with the given arguments. 
        /// 
        /// Metadata for the function to invoke.
        /// Expressions that provide the arguments to the function.
        /// A new DbFunctionExpression representing the function invocation. 
        /// 
        ///      is null, or  is null or contains null. 
        ///  
        /// 
        ///     The count of  does not equal the number of parameters declared by , 
        ///     or  contains an expression that has a result type that is not equal or promotable
        ///     to the corresponding function parameter type.
        /// 
        public static DbFunctionExpression Invoke(this EdmFunction function, params DbExpression[] arguments) 
        {
            return InvokeFunction(function, arguments); 
        } 

        private static DbFunctionExpression InvokeFunction(EdmFunction function, IEnumerable arguments) 
        {
            DbExpressionList validArguments;
            TypeUsage resultType = ArgumentValidation.ValidateFunction(function, arguments, out validArguments);
            return new DbFunctionExpression(resultType, function, validArguments); 
        }
 
        ///  
        /// Creates a new  representing the application of the specified Lambda function to the given arguments.
        ///  
        /// A  instance representing the Lambda function to apply.
        /// A list of expressions that provide the arguments.
        /// A new DbLambdaExpression representing the Lambda function application.
        ///  
        ///      is null, or  is null or contains null.
        ///  
        ///  
        ///     The count of  does not equal the number of variables declared by ,
        ///     or  contains an expression that has a result type that is not equal or promotable 
        ///     to the corresponding variable type.
        /// 
        public static DbLambdaExpression Invoke(this DbLambda lambda, IEnumerable arguments)
        { 
            return InvokeLambda(lambda, arguments);
        } 
 
        /// 
        /// Creates a new  representing the application of the specified Lambda function to the given arguments. 
        /// 
        /// A  instance representing the Lambda function to apply.
        /// Expressions that provide the arguments.
        /// A new DbLambdaExpression representing the Lambda function application. 
        /// 
        ///      is null, or  is null or contains null. 
        ///  
        /// 
        ///     The count of  does not equal the number of variables declared by , 
        ///     or  contains an expression that has a result type that is not equal or promotable
        ///     to the corresponding variable type.
        /// 
        public static DbLambdaExpression Invoke(this DbLambda lambda, params DbExpression[] arguments) 
        {
            return InvokeLambda(lambda, arguments); 
        } 

        private static DbLambdaExpression InvokeLambda(DbLambda lambda, IEnumerable arguments) 
        {
            DbExpressionList validArguments;
            TypeUsage resultType = ArgumentValidation.ValidateInvoke(lambda, arguments, out validArguments);
            return new DbLambdaExpression(resultType, lambda, validArguments); 
        }
 
        ///  
        /// Creates a new . If the type argument is a collection type, the arguments specify the elements of the collection. Otherwise the arguments are used as property or column values in the new instance.
        ///  
        /// The type of the new instance.
        /// Expressions that specify values of the new instances, interpreted according to the instance's type.
        /// A new DbNewInstanceExpression with the specified type and arguments.
        ///  or  is null, or  contains null 
        /// 
        ///      is empty or the result types of the contained expressions do not match the requirements of  (as explained in the remarks section). 
        ///  
        /// 
        ///      
        ///     if  is a a collection type then every expression in  must have a result type that is promotable to the element type of the .
        ///     
        ///     
        ///     if  is a row type,  must contain as many expressions as there are columns in the row 
        ///     type, and the result type of each expression must be equal or promotable to the type of the corresponding column. A row type that does not declare any columns is invalid.
        ///      
        ///      
        ///     if  is an entity type,  must contain as many expressions as there are properties defined by the type,
        ///     and the result type of each expression must be equal or promotable to the type of the corresponding property. 
        ///     
        /// 
        public static DbNewInstanceExpression New(this TypeUsage instanceType, IEnumerable arguments)
        { 
            return NewInstance(instanceType, arguments);
        } 
 
        /// 
        /// Creates a new . If the type argument is a collection type, the arguments specify the elements of the collection. Otherwise the arguments are used as property or column values in the new instance. 
        /// 
        /// The type of the new instance.
        /// Expressions that specify values of the new instances, interpreted according to the instance's type.
        /// A new DbNewInstanceExpression with the specified type and arguments. 
        ///  or  is null, or  contains null
        ///  
        ///      is empty or the result types of the contained expressions do not match the requirements of  (as explained in the remarks section). 
        /// 
        ///  
        ///     
        ///     if  is a a collection type then every expression in  must have a result type that is promotable to the element type of the .
        ///     
        ///      
        ///     if  is a row type,  must contain as many expressions as there are columns in the row
        ///     type, and the result type of each expression must be equal or promotable to the type of the corresponding column. A row type that does not declare any columns is invalid. 
        ///      
        ///     
        ///     if  is an entity type,  must contain as many expressions as there are properties defined by the type, 
        ///     and the result type of each expression must be equal or promotable to the type of the corresponding property.
        ///     
        /// 
        public static DbNewInstanceExpression New(this TypeUsage instanceType, params DbExpression[] arguments) 
        {
            return NewInstance(instanceType, arguments); 
        } 

        private static DbNewInstanceExpression NewInstance(TypeUsage instanceType, IEnumerable arguments) 
        {
            DbExpressionList validArguments;
            TypeUsage resultType = ArgumentValidation.ValidateNew(instanceType, arguments, out validArguments);
            return new DbNewInstanceExpression(resultType, validArguments); 
        }
 
        ///  
        /// Creates a new  that constructs a collection containing the specified elements. The type of the collection is based on the common type of the elements. If no common element type exists an exception is thrown.
        ///  
        /// A list of expressions that provide the elements of the collection
        /// A new DbNewInstanceExpression with the specified collection type and arguments.
        ///  is null, or contains null
        ///  
        ///      is empty or contains expressions for which no common result type exists.
        ///  
        public static DbNewInstanceExpression NewCollection(IEnumerable elements) 
        {
            return CreateNewCollection(elements); 
        }

        /// 
        /// Creates a new  that constructs a collection containing the specified elements. The type of the collection is based on the common type of the elements. If no common element type exists an exception is thrown. 
        /// 
        /// A list of expressions that provide the elements of the collection 
        /// A new DbNewInstanceExpression with the specified collection type and arguments. 
        ///  is null, or contains null
        ///  
        ///      is empty or contains expressions for which no common result type exists.
        /// 
        public static DbNewInstanceExpression NewCollection(params DbExpression[] elements)
        { 
            return CreateNewCollection(elements);
        } 
 
        private static DbNewInstanceExpression CreateNewCollection(IEnumerable elements)
        { 
            DbExpressionList validElements;
            TypeUsage collectionResultType = ArgumentValidation.ValidateNewCollection(elements, out validElements);
            return new DbNewInstanceExpression(collectionResultType, validElements);
        } 

        ///  
        /// Creates a new  that constructs an empty collection of the specified collection type. 
        /// 
        /// The type metadata for the collection to create 
        /// A new DbNewInstanceExpression with the specified collection type and an empty Arguments list.
        ///  is null
        ///  is not a collection type
        public static DbNewInstanceExpression NewEmptyCollection(this TypeUsage collectionType) 
        {
            DbExpressionList validElements; 
            TypeUsage validResultType = ArgumentValidation.ValidateNewEmptyCollection(collectionType, out validElements); 
            return new DbNewInstanceExpression(validResultType, validElements);
        } 


        /// 
        /// Creates a new  that produces a row with the specified named columns and the given values, specified as expressions. 
        /// 
        /// A list of string-DbExpression key-value pairs that defines the structure and values of the row. 
        /// A new DbNewInstanceExpression that represents the construction of the row. 
        ///  is null or contains an element with a null column name or expression
        ///  
        ///      is empty, or contains a duplicate or invalid column name
        /// 
        public static DbNewInstanceExpression NewRow(IEnumerable> columnValues)
        { 
            DbExpressionList validElements;
            TypeUsage resultType = ArgumentValidation.ValidateNewRow(columnValues, out validElements); 
            return new DbNewInstanceExpression(resultType, validElements); 
        }
 
        /// 
        /// Creates a new  representing the retrieval of the specified property.
        /// 
        /// The instance from which to retrieve the property. May be null if the property is static. 
        /// Metadata for the property to retrieve.
        /// A new DbPropertyExpression representing the property retrieval. 
        ///  is null or  is null and the property is not static. 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "required for this feature")]
        public static DbPropertyExpression Property(this DbExpression instance, EdmProperty propertyMetadata) 
        {
            return PropertyFromMember(instance, propertyMetadata, "propertyMetadata");
        }
 
        /// 
        /// Creates a new  representing the retrieval of the specified navigation property. 
        ///  
        /// The instance from which to retrieve the navigation property.
        /// Metadata for the navigation property to retrieve. 
        /// A new DbPropertyExpression representing the navigation property retrieval.
        ///  is null or  is null.
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "required for this feature")]
        public static DbPropertyExpression Property(this DbExpression instance, NavigationProperty navigationProperty) 
        {
            return PropertyFromMember(instance, navigationProperty, "navigationProperty"); 
        } 

        ///  
        /// Creates a new  representing the retrieval of the specified relationship end member.
        /// 
        /// The instance from which to retrieve the relationship end member.
        /// Metadata for the relationship end member to retrieve. 
        /// A new DbPropertyExpression representing the relationship end member retrieval.
        ///  is null or  is null and the property is not static. 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "required for this feature")] 
        public static DbPropertyExpression Property(this DbExpression instance, RelationshipEndMember relationshipEnd)
        { 
            return PropertyFromMember(instance, relationshipEnd, "relationshipEnd");
        }

        ///  
        /// Creates a new  representing the retrieval of the instance property with the specified name from the given instance.
        ///  
        /// The name of the property to retrieve. 
        /// The instance from which to retrieve the property.
        /// A new DbPropertyExpression that represents the property retrieval 
        ///  is null or  is null and the property is not static.
        /// No property with the specified name is declared by the type of .
        public static DbPropertyExpression Property(this DbExpression instance, string propertyName)
        { 
            return PropertyByName(instance, propertyName, false);
        } 
 
        /// 
        /// Creates a new  representing the retrieval of the instance property with the specified name from the given instance. 
        /// A case-insensitive lookup for a property with the specified name is performed on the result type of .
        /// 
        /// The name of the property to retrieve.
        /// The instance from which to retrieve the property. 
        /// A new DbPropertyExpression that represents the property retrieval
        ///  is null or  is null and the property is not static. 
        /// No property with the specified name is declared by the type of . 
        public static DbPropertyExpression PropertyIgnoreCase(this DbExpression instance, string propertyName)
        { 
            return PropertyByName(instance, propertyName, true);
        }

        private static DbPropertyExpression PropertyFromMember(DbExpression instance, EdmMember property, string propertyArgumentName) 
        {
            TypeUsage resultType = ArgumentValidation.ValidateProperty(instance, property, propertyArgumentName); 
            return new DbPropertyExpression(resultType, property, instance); 
        }
 
        private static DbPropertyExpression PropertyByName(DbExpression instance, string propertyName, bool ignoreCase)
        {
            EdmMember property;
            TypeUsage resultType = ArgumentValidation.ValidateProperty(instance, propertyName, ignoreCase, out property); 
            return new DbPropertyExpression(resultType, property, instance);
        } 
 
        #endregion
 
        #region Lambda-based methods: All, Any, Cross|OuterApply, Cross|FullOuter|Inner|LeftOuterJoin, Filter, GroupBy, Project, Skip, Sort

        private static string ExtractAlias(MethodInfo method)
        { 
            Debug.Assert(method != null, "Ensure method is non-null before calling ExtractAlias");
            string[] aliases = ExtractAliases(method); 
            Debug.Assert(aliases.Length > 0, "Incompatible method: at least one parameter is required"); 
            return aliases[0];
        } 

        internal static string[] ExtractAliases(MethodInfo method)
        {
            Debug.Assert(method != null, "Ensure method is non-null before calling ExtractAlias"); 
            ParameterInfo[] methodParams = method.GetParameters();
            int start; 
            int paramCount; 
            if (method.IsStatic && typeof(System.Runtime.CompilerServices.Closure) == methodParams[0].ParameterType)
            { 
                // Static lambda method has additional first closure parameter
                start = 1;
                paramCount = methodParams.Length - 1;
            } 
            else
            { 
                // Otherwise, method parameters align directly with arguments 
                start = 0;
                paramCount = methodParams.Length; 
            }

            string[] paramNames = new string[paramCount];
            bool generateNames = methodParams.Skip(start).Any(p => p.Name == null); 
            for (int idx = start; idx < methodParams.Length; idx++)
            { 
                paramNames[idx - start] = (generateNames ? _bindingAliases.Next() : methodParams[idx].Name); 
            }
            return paramNames; 
        }

        private static DbExpressionBinding ConvertToBinding(DbExpression source, Func argument, string argumentName, out TResult argumentResult)
        { 
            return ConvertToBinding(source, "source", argument, argumentName, out argumentResult);
        } 
 
        private static DbExpressionBinding ConvertToBinding(DbExpression source, string sourceName, Func argument, string argumentName, out TResult argumentResult)
        { 
            EntityUtil.CheckArgumentNull(source, sourceName);
            EntityUtil.CheckArgumentNull(argument, argumentName);
            string alias = ExtractAlias(argument.Method);
            DbExpressionBinding binding = DbExpressionBuilder.BindAs(source, alias); 
            argumentResult = argument(binding.Variable);
            return binding; 
        } 

        private static DbExpressionBinding[] ConvertToBinding(DbExpression left, string leftArgumentName, DbExpression right, string rightArgumentName, Func argument, string argumentName, out DbExpression argumentExp) 
        {
            EntityUtil.CheckArgumentNull(left, leftArgumentName);
            EntityUtil.CheckArgumentNull(right, rightArgumentName);
 
            EntityUtil.CheckArgumentNull(argument, argumentName);
            string[] aliases = ExtractAliases(argument.Method); 
            DbExpressionBinding leftBinding = DbExpressionBuilder.BindAs(left, aliases[0]); 
            DbExpressionBinding rightBinding = DbExpressionBuilder.BindAs(right, aliases[1]);
            argumentExp = argument(leftBinding.Variable, rightBinding.Variable); 
            return new[] { leftBinding, rightBinding };
        }

        [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] 
        private static bool TryGetAnonymousTypeValues(object instance, out List> values)
        { 
            Debug.Assert(instance != null, "Ensure instance is non-null before calling TryGetAnonymousTypeValues"); 

            // The following heuristic is used to approximate whether or not TInstance is an anonymous type: 
            // - Derived directly from System.Object
            // - Declares only public instance properties
            // - All public instance properties are readable and of an appropriate type
 
            values = null;
            if (typeof(TInstance).BaseType.Equals(typeof(object)) && 
                typeof(TInstance).GetProperties(BindingFlags.Static).Length == 0 && 
                typeof(TInstance).GetProperties(BindingFlags.Instance | BindingFlags.NonPublic).Length == 0)
            { 
                List> foundValues = null;
                foreach (PropertyInfo pi in typeof(TInstance).GetProperties(BindingFlags.Public | BindingFlags.Instance))
                {
                    if (pi.CanRead && typeof(TRequired).IsAssignableFrom(pi.PropertyType)) 
                    {
                        if (foundValues == null) 
                        { 
                            foundValues = new List>();
                        } 
                        foundValues.Add(new KeyValuePair(pi.Name, (TRequired)pi.GetValue(instance, null)));
                    }
                    else
                    { 
                        foundValues = null;
                        break; 
                    } 
                }
                values = foundValues; 
            }

            return (values != null);
        } 

        private static bool TryResolveToConstant(Type type, object value, out DbExpression constantOrNullExpression) 
        { 
            constantOrNullExpression = null;
 
            Type valueType = type;
            if (type.IsGenericType && typeof(Nullable<>).Equals(type.GetGenericTypeDefinition()))
            {
                valueType = type.GetGenericArguments()[0]; 
            }
 
            PrimitiveType primitiveType = null; 
            if (ClrProviderManifest.Instance.TryGetPrimitiveType(valueType, out primitiveType))
            { 
                TypeUsage resultType = TypeHelpers.GetLiteralTypeUsage(primitiveType.PrimitiveTypeKind);
                if (null == value)
                {
                    constantOrNullExpression = DbExpressionBuilder.Null(resultType); 
                }
                else 
                { 
                    constantOrNullExpression = DbExpressionBuilder.Constant(resultType, value);
                } 
            }

            return (constantOrNullExpression != null);
        } 

        private static DbExpression ResolveToExpression(TArgument argument) 
        { 
            object untypedArgument = argument;
 
            DbExpression constantResult;
            if (TryResolveToConstant(typeof(TArgument), untypedArgument, out constantResult))
            {
                return constantResult; 
            }
 
            if (null == untypedArgument) 
            {
                return (DbExpression)null; 
            }

            // Direct DbExpression result
            if (typeof(DbExpression).IsAssignableFrom(typeof(TArgument))) 
            {
                return (DbExpression)untypedArgument; 
            } 

            // Row 
            if (typeof(Row).Equals(typeof(TArgument)))
            {
                return ((Row)untypedArgument).ToExpression();
            } 

            // Conversion from anonymous type instance to DbNewInstanceExpression of a corresponding row type 
            List> columnValues; 
            if (TryGetAnonymousTypeValues(untypedArgument, out columnValues))
            { 
                return DbExpressionBuilder.NewRow(columnValues);
            }

            // The specified instance cannot be resolved to a DbExpression 
            throw EntityUtil.NotSupported(Entity.Strings.Cqt_Factory_MethodResultTypeNotSupported(typeof(TArgument).FullName));
        } 
 
        private static DbApplyExpression CreateApply(DbExpression source, Func> apply, Func resultBuilder)
        { 
            KeyValuePair applyTemplate;
            DbExpressionBinding sourceBinding = ConvertToBinding(source, apply, "apply", out applyTemplate);
            DbExpressionBinding applyBinding = DbExpressionBuilder.BindAs(applyTemplate.Value, applyTemplate.Key);
            return resultBuilder(sourceBinding, applyBinding); 
        }
 
        ///  
        /// Creates a new  that determines whether the given predicate holds for all elements of the input set.
        ///  
        /// 
        ///     An expression that specifies the input set.
        /// 
        ///  
        ///    A method representing a predicate to evaluate for each member of the input set.
        ///    This method must produce an expression with a Boolean result type that provides 
        ///    the predicate logic. 
        /// 
        /// A new DbQuantifierExpression that represents the All operation. 
        ///  or  is null
        /// The expression produced by  is null
        ///  does not have a collection result type.
        ///  
        ///     The expression produced by  does not have a Boolean result type.
        ///  
        public static DbQuantifierExpression All(this DbExpression source, Func predicate) 
        {
            DbExpression predicateExp; 
            DbExpressionBinding input = ConvertToBinding(source, predicate, "predicate", out predicateExp);
            return DbExpressionBuilder.All(input, predicateExp);
        }
 
        /// 
        /// Creates a new  that determines whether the specified set argument is non-empty. 
        ///  
        /// An expression that specifies the input set
        /// A new  applied to a new  with the specified argument. 
        ///  is null
        ///  does not have a collection result type.
        public static DbExpression Any(this DbExpression source)
        { 
            return DbExpressionBuilder.Exists(source);
        } 
 
        /// 
        /// Creates a new  that determines whether the specified set argument is non-empty. 
        /// 
        /// An expression that specifies the input set
        /// A new  applied to a new  with the specified argument.
        ///  is null 
        ///  does not have a collection result type.
        public static DbExpression Exists(this DbExpression argument) 
        { 
            return DbExpressionBuilder.Not(DbExpressionBuilder.IsEmpty(argument));
        } 

        /// 
        /// Creates a new  that determines whether the given predicate holds for any element of the input set.
        ///  
        /// 
        ///     An expression that specifies the input set. 
        ///  
        /// 
        ///    A method representing the predicate to evaluate for each member of the input set. 
        ///    This method must produce an expression with a Boolean result type that provides
        ///    the predicate logic.
        /// 
        /// A new DbQuantifierExpression that represents the Any operation. 
        ///  or  is null
        /// The expression produced by  is null 
        ///  does not have a collection result type. 
        /// 
        ///     The expression produced by  does not have a Boolean result type. 
        /// 
        public static DbQuantifierExpression Any(this DbExpression source, Func predicate)
        {
            DbExpression predicateExp; 
            DbExpressionBinding input = ConvertToBinding(source, predicate, "predicate", out predicateExp);
            return DbExpressionBuilder.Any(input, predicateExp); 
        } 

        ///  
        /// Creates a new  that evaluates the given  expression once for each element of a given input set,
        /// producing a collection of rows with corresponding input and apply columns. Rows for which  evaluates to an empty set are not included.
        /// 
        ///  
        ///     A  that specifies the input set.
        ///  
        ///  
        ///     A method that specifies the logic to evaluate once for each member of the input set.
        ///  
        /// An new DbApplyExpression with the specified input and apply bindings and an  of CrossApply.
        ///  or  is null
        ///  does not have a collection result type.
        /// The result of  contains a name or expression that is null. 
        /// The result of  contains a name or expression that is not valid in an expression binding.
        public static DbApplyExpression CrossApply(this DbExpression source, Func> apply) 
        { 
            return CreateApply(source, apply, DbExpressionBuilder.CrossApply);
        } 

        //

 
        /// 
        /// Creates a new  that evaluates the given  expression once for each element of a given input set, 
        /// producing a collection of rows with corresponding input and apply columns. Rows for which  evaluates to an empty set have an apply column value of null. 
        /// 
        ///  
        ///     A  that specifies the input set.
        /// 
        /// 
        ///     A method that specifies the logic to evaluate once for each member of the input set. 
        /// 
        /// An new DbApplyExpression with the specified input and apply bindings and an  of OuterApply. 
        ///  or  is null 
        ///  does not have a collection result type.
        /// The result of  contains a name or expression that is null. 
        /// The result of  contains a name or expression that is not valid in an expression binding.
        public static DbApplyExpression OuterApply(this DbExpression source, Func> apply)
        {
            return CreateApply(source, apply, DbExpressionBuilder.OuterApply); 
        }
 
        // 

 
        //

        /// 
        /// Creates a new  that joins the sets specified by the left and right expressions, 
        /// on the specified join condition, using FullOuterJoin as the .
        ///  
        /// A  that specifies the left set argument. 
        /// A  that specifies the right set argument.
        ///  
        ///     A method representing the condition on which to join.
        ///    This method must produce an expression with a Boolean result type that provides the
        ///    logic of the join condition.
        ///  
        /// 
        ///     A new DbJoinExpression, with an  of FullOuterJoin, that represents the full outer join operation 
        ///     applied to the left and right input sets under the given join condition. 
        /// 
        ///  
        ///     ,  or  is null.
        /// 
        /// 
        ///      or  does not have a collection result type. 
        /// 
        ///  
        ///     The expression produced by  is null. 
        /// 
        ///  
        ///     The expression produced by  does not have a Boolean result type.
        /// 
        public static DbJoinExpression FullOuterJoin(this DbExpression left, DbExpression right, Func joinCondition)
        { 
            DbExpression condExp;
            DbExpressionBinding[] inputs = ConvertToBinding(left, "left", right, "right", joinCondition, "joinCondition", out condExp); 
            return DbExpressionBuilder.FullOuterJoin(inputs[0], inputs[1], condExp); 
        }
 
        /// 
        /// Creates a new  that joins the sets specified by the left and right expressions,
        /// on the specified join condition, using InnerJoin as the .
        ///  
        /// A  that specifies the left set argument.
        /// A  that specifies the right set argument. 
        ///  
        ///     A method representing the condition on which to join.
        ///    This method must produce an expression with a Boolean result type that provides the 
        ///    logic of the join condition.
        /// 
        /// 
        ///     A new DbJoinExpression, with an  of InnerJoin, that represents the inner join operation 
        ///     applied to the left and right input sets under the given join condition.
        ///  
        ///  
        ///     ,  or  is null.
        ///  
        /// 
        ///      or  does not have a collection result type.
        /// 
        ///  
        ///     The expression produced by  is null.
        ///  
        ///  
        ///     The expression produced by  does not have a Boolean result type.
        ///  
        public static DbJoinExpression InnerJoin(this DbExpression left, DbExpression right, Func joinCondition)
        {
            DbExpression condExp;
            DbExpressionBinding[] inputs = ConvertToBinding(left, "left", right, "right", joinCondition, "joinCondition", out condExp); 
            return DbExpressionBuilder.InnerJoin(inputs[0], inputs[1], condExp);
        } 
 
        /// 
        /// Creates a new  that joins the sets specified by the left and right expressions, 
        /// on the specified join condition, using LeftOuterJoin as the .
        /// 
        /// A  that specifies the left set argument.
        /// A  that specifies the right set argument. 
        /// 
        ///     A method representing the condition on which to join. 
        ///    This method must produce an expression with a Boolean result type that provides the 
        ///    logic of the join condition.
        ///  
        /// 
        ///     A new DbJoinExpression, with an  of LeftOuterJoin, that represents the left outer join operation
        ///     applied to the left and right input sets under the given join condition.
        ///  
        /// 
        ///     ,  or  is null. 
        ///  
        /// 
        ///      or  does not have a collection result type. 
        /// 
        /// 
        ///     The expression produced by  is null.
        ///  
        /// 
        ///     The expression produced by  does not have a Boolean result type. 
        ///  
        public static DbJoinExpression LeftOuterJoin(this DbExpression left, DbExpression right, Func joinCondition)
        { 
            DbExpression condExp;
            DbExpressionBinding[] inputs = ConvertToBinding(left, "left", right, "right", joinCondition, "joinCondition", out condExp);
            return DbExpressionBuilder.LeftOuterJoin(inputs[0], inputs[1], condExp);
        } 

        ///  
        /// Creates a new  that joins the sets specified by the outer and inner expressions, 
        /// on an equality condition between the specified outer and inner keys, using InnerJoin as the .
        ///  
        /// A  that specifies the outer set argument.
        /// A  that specifies the inner set argument.
        /// A method that specifies how the outer key value should be derived from an element of the outer set.
        /// A method that specifies how the inner key value should be derived from an element of the inner set. 
        /// 
        ///     A new DbJoinExpression, with an  of InnerJoin, that represents the inner join operation 
        ///     applied to the left and right input sets under a join condition that compares the outer and inner key values for equality. 
        /// 
        ///  
        ///     , ,  or  is null.
        /// 
        /// 
        ///      or  does not have a collection result type. 
        /// 
        ///  
        ///     The expression produced by  or  is null. 
        /// 
        ///  
        ///     The expressions produced by  and  are not comparable for equality.
        /// 
        public static DbJoinExpression Join(this DbExpression outer, DbExpression inner, Func outerKey, Func innerKey)
        { 
            DbExpression leftOperand;
            DbExpressionBinding leftBinding = ConvertToBinding(outer, "outer", outerKey, "outerKey", out leftOperand); 
 
            DbExpression rightOperand;
            DbExpressionBinding rightBinding = ConvertToBinding(inner, "inner", innerKey, "innerKey", out rightOperand); 

            DbExpression joinCondition = DbExpressionBuilder.Equal(leftOperand, rightOperand);

            return DbExpressionBuilder.InnerJoin(leftBinding, rightBinding, joinCondition); 
        }
 
        ///  
        /// Creates a new  that projects the specified selector over the sets specified by the outer and inner
        /// expressions, joined on an equality condition between the specified outer and inner keys, using InnerJoin as the . 
        /// 
        /// A  that specifies the outer set argument.
        /// A  that specifies the inner set argument.
        /// A method that specifies how the outer key value should be derived from an element of the outer set. 
        /// A method that specifies how the inner key value should be derived from an element of the inner set.
        ///  
        ///    A method that specifies how an element of the result set should be derived from elements of the inner and outer sets. 
        ///    This method must produce an instance of a type that is compatible with Join and can be resolved
        ///    into a . 
        ///    Compatibility requirements for  are described in remarks.
        /// 
        /// 
        ///     A new DbProjectExpression with the specified selector as its projection, and a new DbJoinExpression as its input. 
        ///     The input DbJoinExpression is created with an  of InnerJoin, that represents the inner join operation
        ///     applied to the left and right input sets under a join condition that compares the outer and inner key values for equality. 
        ///  
        /// 
        ///     , , ,  or  is null. 
        /// 
        /// 
        ///      or  does not have a collection result type.
        ///  
        /// 
        ///     The expression produced by  or  is null. 
        ///  
        /// 
        ///     The result of  is null after conversion to DbExpression. 
        /// 
        /// 
        ///     The expressions produced by  and  are not comparable for equality.
        ///  
        /// 
        ///     The result of  is not compatible with SelectMany. 
        ///  
        /// 
        ///     To be compatible with Join,  must be derived from , 
        ///     or must be an anonymous type with DbExpression-derived properties.
        ///     
        ///     The following are examples of supported types for :
        ///     outer.Join(inner, o => o.Property("ID"), i => i.Property("ID"), (o, i) => o.Property("Name")) ( is ). 
        ///     outer.Join(inner, o => o.Property("ID"), i => i.Property("ID"), (o, i) => new { OName = o.Property("Name"), IName = i.Property("Name") }) ( is an anonymous type with DbExpression-derived properties).
        ///      
        ///  
        public static DbProjectExpression Join(this DbExpression outer, DbExpression inner, Func outerKey, Func innerKey, Func selector)
        { 
            // Defer argument validation for all but the selector to the selector-less overload of Join
            DbJoinExpression joinExpression = DbExpressionBuilder.Join(outer, inner, outerKey, innerKey);

            // Ensure that the selector is non-null; 
            EntityUtil.CheckArgumentNull(selector, "selector");
 
            // Bind the join expression and produce the selector based on the left and right inputs 
            DbExpressionBinding joinBinding = DbExpressionBuilder.Bind(joinExpression);
            DbExpression left = DbExpressionBuilder.Property(joinBinding.Variable, joinExpression.Left.VariableName); 
            DbExpression right = DbExpressionBuilder.Property(joinBinding.Variable, joinExpression.Right.VariableName);
            TSelector intermediateSelector = selector(left, right);
            DbExpression projection = DbExpressionBuilder.ResolveToExpression(intermediateSelector);
 
            // Project the selector over the join expression and return the resulting DbProjectExpression
            return DbExpressionBuilder.Project(joinBinding, projection); 
        } 

        ///  
        /// Creates a new  that sorts the given input set by the specified sort key,
        /// with ascending sort order and default collation.
        /// 
        /// An expression that specifies the input set. 
        /// 
        ///    A method that specifies how to derive the sort key expression given a member of the input set. 
        ///    This method must produce an expression with an order-comparable result type that provides the 
        ///    sort key definition.
        ///  
        /// A new DbSortExpression that represents the order-by operation.
        ///  or  is null.
        /// The expression produced by  is null.
        ///  does not have a collection result type. 
        /// 
        ///     The expression produced by  does not have an order-comparable result type. 
        ///  
        public static DbSortExpression OrderBy(this DbExpression source, Func sortKey)
        { 
            DbExpression keyExpression;
            DbExpressionBinding input = ConvertToBinding(source, sortKey, "sortKey", out keyExpression);
            DbSortClause sortClause = DbExpressionBuilder.ToSortClause(keyExpression);
            return DbExpressionBuilder.Sort(input, new DbSortClause[] { sortClause }); 
        }
 
        ///  
        /// Creates a new  that sorts the given input set by the specified sort key,
        /// with ascending sort order and the specified collation. 
        /// 
        /// An expression that specifies the input set.
        /// 
        ///    A method that specifies how to derive the sort key expression given a member of the input set. 
        ///    This method must produce an expression with an order-comparable result type that provides the
        ///    sort key definition. 
        ///  
        /// The collation to sort under
        /// A new DbSortExpression that represents the order-by operation. 
        /// ,   or  is null.
        /// The expression produced by  is null.
        ///  does not have a collection result type.
        ///  
        ///     The expression produced by  does not have an order-comparable string result type.
        ///  
        ///  is empty or contains only space characters 
        public static DbSortExpression OrderBy(this DbExpression source, Func sortKey, string collation)
        { 
            DbExpression keyExpression;
            DbExpressionBinding input = ConvertToBinding(source, sortKey, "sortKey", out keyExpression);
            DbSortClause sortClause = DbExpressionBuilder.ToSortClause(keyExpression, collation);
            return DbExpressionBuilder.Sort(input, new DbSortClause[] { sortClause }); 
        }
 
        ///  
        /// Creates a new  that sorts the given input set by the specified sort key,
        /// with descending sort order and default collation. 
        /// 
        /// An expression that specifies the input set.
        /// 
        ///    A method that specifies how to derive the sort key expression given a member of the input set. 
        ///    This method must produce an expression with an order-comparable result type that provides the
        ///    sort key definition. 
        ///  
        /// A new DbSortExpression that represents the order-by operation.
        ///  or  is null. 
        /// The expression produced by  is null.
        ///  does not have a collection result type.
        /// 
        ///     The expression produced by  does not have an order-comparable result type. 
        /// 
        public static DbSortExpression OrderByDescending(this DbExpression source, Func sortKey) 
        { 
            DbExpression keyExpression;
            DbExpressionBinding input = ConvertToBinding(source, sortKey, "sortKey", out keyExpression); 
            DbSortClause sortClause = DbExpressionBuilder.ToSortClauseDescending(keyExpression);
            return DbExpressionBuilder.Sort(input, new DbSortClause[] { sortClause });
        }
 
        /// 
        /// Creates a new  that sorts the given input set by the specified sort key, 
        /// with descending sort order and the specified collation. 
        /// 
        /// An expression that specifies the input set. 
        /// 
        ///    A method that specifies how to derive the sort key expression given a member of the input set.
        ///    This method must produce an expression with an order-comparable result type that provides the
        ///    sort key definition. 
        /// 
        /// The collation to sort under 
        /// A new DbSortExpression that represents the order-by operation. 
        /// ,   or  is null.
        /// The expression produced by  is null. 
        ///  does not have a collection result type.
        /// 
        ///     The expression produced by  does not have an order-comparable string result type.
        ///  
        ///  is empty or contains only space characters
        public static DbSortExpression OrderByDescending(this DbExpression source, Func sortKey, string collation) 
        { 
            DbExpression keyExpression;
            DbExpressionBinding input = ConvertToBinding(source, sortKey, "sortKey", out keyExpression); 
            DbSortClause sortClause = DbExpressionBuilder.ToSortClauseDescending(keyExpression, collation);
            return DbExpressionBuilder.Sort(input, new DbSortClause[] { sortClause });
        }
 
        /// 
        /// Creates a new  that selects the specified expression over the given input set. 
        ///  
        /// An expression that specifies the input set.
        ///  
        ///    A method that specifies how to derive the projected expression given a member of the input set.
        ///    This method must produce an instance of a type that is compatible with Select and can be resolved
        ///    into a .
        ///    Compatibility requirements for  are described in remarks. 
        /// 
        /// The method result type of . 
        /// A new DbProjectExpression that represents the select operation. 
        ///  or  is null
        /// The result of  is null. 
        /// 
        ///     To be compatible with Select,  must be derived from ,
        ///     or must be an anonymous type with DbExpression-derived properties.
        ///      
        ///     The following are examples of supported types for :
        ///     source.Select(x => x.Property("Name")) ( is ). 
        ///     source.Select(x => new { Name = x.Property("Name") }) ( is an anonymous type with a DbExpression-derived property). 
        ///     
        ///  
        public static DbProjectExpression Select(this DbExpression source, Func projection)
        {
            EntityUtil.CheckArgumentNull(projection, "projection");
            TProjection intermediateProjection; 
            DbExpressionBinding input = ConvertToBinding(source, projection, "projection", out intermediateProjection);
            DbExpression projectionExp = ResolveToExpression(intermediateProjection); 
            return DbExpressionBuilder.Project(input, projectionExp); 
        }
 
        /// 
        /// Creates a new  that evaluates the given  expression once for each element of a given input set,
        /// producing a collection of rows with corresponding input and apply columns. Rows for which  evaluates to an empty set are not included.
        /// A  is then created that selects the  column from each row, producing the overall collection of  results. 
        /// 
        ///  
        ///     A  that specifies the input set. 
        /// 
        ///  
        ///     A method that represents the logic to evaluate once for each member of the input set.
        /// 
        /// An new DbProjectExpression that selects the apply column from a new DbApplyExpression with the specified input and apply bindings and an  of CrossApply.
        ///  or  is null. 
        /// The expression produced by  is null.
        ///  does not have a collection result type. 
        /// The expression produced by  does not have a collection type. 
        public static DbProjectExpression SelectMany(this DbExpression source, Func apply)
        { 
            DbExpression functorResult;
            DbExpressionBinding inputBinding = ConvertToBinding(source, apply, "apply", out functorResult);

            DbExpressionBinding functorBinding = DbExpressionBuilder.Bind(functorResult); 
            DbApplyExpression intermediateApply = DbExpressionBuilder.CrossApply(inputBinding, functorBinding);
 
            DbExpressionBinding projectionBinding = DbExpressionBuilder.Bind(intermediateApply); 
            return DbExpressionBuilder.Project(projectionBinding, DbExpressionBuilder.Property(projectionBinding.Variable, functorBinding.VariableName));
        } 

        /// 
        /// Creates a new  that evaluates the given  expression once for each element of a given input set,
        /// producing a collection of rows with corresponding input and apply columns. Rows for which  evaluates to an empty set are not included. 
        /// A  is then created that selects the specified  over each row, producing the overall collection of results.
        ///  
        /// The method result type of . 
        /// 
        ///     A  that specifies the input set. 
        /// 
        /// 
        ///     A method that represents the logic to evaluate once for each member of the input set.
        ///  
        /// 
        ///    A method that specifies how an element of the result set should be derived given an element of the input and apply sets. 
        ///    This method must produce an instance of a type that is compatible with SelectMany and can be resolved into a . 
        ///    Compatibility requirements for  are described in remarks.
        ///  
        /// An new DbProjectExpression that selects the result of the given selector from a new DbApplyExpression with the specified input and apply bindings and an  of CrossApply.
        /// ,  or  is null.
        /// The expression produced by  is null.
        /// The result of  is null on conversion to DbExpression 
        ///  does not have a collection result type.
        /// The expression produced by  does not have a collection type. 
        ///  
        ///     To be compatible with SelectMany,  must be derived from ,
        ///     or must be an anonymous type with DbExpression-derived properties. 
        ///     
        ///     The following are examples of supported types for :
        ///     source.SelectMany(x => x.Property("RelatedCollection"), (source, apply) => apply.Property("Name")) ( is ).
        ///     source.SelectMany(x => x.Property("RelatedCollection"), (source, apply) => new { SourceName = source.Property("Name"), RelatedName = apply.Property("Name") }) ( is an anonymous type with DbExpression-derived properties). 
        ///     
        ///  
        public static DbProjectExpression SelectMany(this DbExpression source, Func apply, Func selector) 
        {
            DbExpression functorResult; 
            DbExpressionBinding inputBinding = ConvertToBinding(source, apply, "apply", out functorResult);
            EntityUtil.CheckArgumentNull(selector, "selector");

            DbExpressionBinding functorBinding = DbExpressionBuilder.Bind(functorResult); 
            DbApplyExpression intermediateApply = DbExpressionBuilder.CrossApply(inputBinding, functorBinding);
 
            DbExpressionBinding projectionBinding = DbExpressionBuilder.Bind(intermediateApply); 
            DbExpression left = DbExpressionBuilder.Property(projectionBinding.Variable, inputBinding.VariableName);
            DbExpression right = DbExpressionBuilder.Property(projectionBinding.Variable, functorBinding.VariableName); 
            TSelector selectorResult = selector(left, right);
            DbExpression projection = ResolveToExpression(selectorResult);
            return DbExpressionBuilder.Project(projectionBinding, projection);
        } 

        ///  
        /// Creates a new  that skips the specified number of elements from the given sorted input set. 
        /// 
        /// A  that specifies the sorted input set. 
        /// An expression the specifies how many elements of the ordered set to skip.
        /// A new DbSkipExpression that represents the skip operation.
        /// 
        ///      or  is null. 
        /// 
        ///  
        ///      is not  or  or has a 
        ///     result type that is not equal or promotable to a 64-bit integer type.
        ///  
        public static DbSkipExpression Skip(this DbSortExpression argument, DbExpression count)
        {
            EntityUtil.CheckArgumentNull(argument, "argument");
            return DbExpressionBuilder.Skip(argument.Input, argument.SortOrder, count); 
        }
 
        ///  
        /// Creates a new  that restricts the number of elements in the Argument collection to the specified count Limit value.
        /// Tied results are not included in the output. 
        /// 
        /// An expression that specifies the input collection.
        /// An expression that specifies the limit value.
        /// A new DbLimitExpression with the specified argument and count limit values that does not include tied results. 
        ///  or  is null
        ///  
        ///      does not have a collection result type, 
        ///     or  does not have a result type that is equal or promotable to a 64-bit integer type.
        ///  
        public static DbLimitExpression Take(this DbExpression argument, DbExpression count)
        {
            return DbExpressionBuilder.Limit(argument, count);
        } 

        private static DbSortExpression CreateThenBy(DbSortExpression source, Func sortKey, bool ascending, string collation, bool useCollation) 
        { 
            EntityUtil.CheckArgumentNull(source, "source");
            EntityUtil.CheckArgumentNull(sortKey, "sortKey"); 
            DbExpression sortKeyResult = sortKey(source.Input.Variable);
            DbSortClause sortClause;
            if (useCollation)
            { 
                sortClause = (ascending ? DbExpressionBuilder.ToSortClause(sortKeyResult, collation) : DbExpressionBuilder.ToSortClauseDescending(sortKeyResult, collation));
            } 
            else 
            {
                sortClause = (ascending ? DbExpressionBuilder.ToSortClause(sortKeyResult) : DbExpressionBuilder.ToSortClauseDescending(sortKeyResult)); 
            }

            List newSortOrder = new List(source.SortOrder.Count + 1);
            newSortOrder.AddRange(source.SortOrder); 
            newSortOrder.Add(sortClause);
 
            return DbExpressionBuilder.Sort(source.Input, newSortOrder); 
        }
 
        /// 
        /// Creates a new  that with a sort order that includes the sort order
        /// of the given order input set together with the specified sort key in ascending sort order and
        /// with default collation. 
        /// 
        /// A DbSortExpression that specifies the ordered input set. 
        ///  
        ///    A method that specifies how to derive the additional sort key expression given a member of the
        ///    input set. 
        ///    This method must produce an expression with an order-comparable result type that provides the
        ///    sort key definition.
        /// 
        /// A new DbSortExpression that represents the new overall order-by operation. 
        ///  or   is null.
        /// The expression produced by  is null. 
        ///  does not have a collection result type. 
        /// 
        ///     The expression produced by  does not have an order-comparable result type. 
        /// 
        public static DbSortExpression ThenBy(this DbSortExpression source, Func sortKey)
        {
            return CreateThenBy(source, sortKey, true, null, false); 
        }
 
        ///  
        /// Creates a new  that with a sort order that includes the sort order
        /// of the given order input set together with the specified sort key in ascending sort order and 
        /// with the specified collation.
        /// 
        /// A DbSortExpression that specifies the ordered input set.
        ///  
        ///    A method that specifies how to derive the additional sort key expression given a member of the
        ///    input set. 
        ///    This method must produce an expression with an order-comparable result type that provides the 
        ///    sort key definition.
        ///  
        /// The collation to sort under
        /// A new DbSortExpression that represents the new overall order-by operation.
        /// ,   or  is null.
        /// The expression produced by  is null. 
        ///  does not have a collection result type.
        ///  
        ///     The expression produced by  does not have an order-comparable string result type. 
        /// 
        ///  is empty or contains only space characters 
        public static DbSortExpression ThenBy(this DbSortExpression source, Func sortKey, string collation)
        {
            return CreateThenBy(source, sortKey, true, collation, true);
        } 

        ///  
        /// Creates a new  that with a sort order that includes the sort order 
        /// of the given order input set together with the specified sort key in descending sort order and
        /// with default collation. 
        /// 
        /// A DbSortExpression that specifies the ordered input set.
        /// 
        ///    A method that specifies how to derive the additional sort key expression given a member of the 
        ///    input set.
        ///    This method must produce an expression with an order-comparable result type that provides the 
        ///    sort key definition. 
        /// 
        /// A new DbSortExpression that represents the new overall order-by operation. 
        ///  or   is null.
        /// The expression produced by  is null.
        ///  does not have a collection result type.
        ///  
        ///     The expression produced by  does not have an order-comparable result type.
        ///  
        public static DbSortExpression ThenByDescending(this DbSortExpression source, Func sortKey) 
        {
            return CreateThenBy(source, sortKey, false, null, false); 
        }

        /// 
        /// Creates a new  that with a sort order that includes the sort order 
        /// of the given order input set together with the specified sort key in descending sort order and
        /// with the specified collation. 
        ///  
        /// A DbSortExpression that specifies the ordered input set.
        ///  
        ///    A method that specifies how to derive the additional sort key expression given a member of the
        ///    input set.
        ///    This method must produce an expression with an order-comparable result type that provides the
        ///    sort key definition. 
        /// 
        /// The collation to sort under 
        /// A new DbSortExpression that represents the new overall order-by operation. 
        /// ,   or  is null.
        /// The expression produced by  is null. 
        ///  does not have a collection result type.
        /// 
        ///     The expression produced by  does not have an order-comparable string result type.
        ///  
        ///  is empty or contains only space characters
        public static DbSortExpression ThenByDescending(this DbSortExpression source, Func sortKey, string collation) 
        { 
            return CreateThenBy(source, sortKey, false, collation, true);
        } 

        /// 
        /// Creates a new  that filters the elements in the given input set using the specified predicate.
        ///  
        /// 
        ///     An expression that specifies the input set. 
        ///  
        /// 
        ///    A method representing the predicate to evaluate for each member of the input set. 
        ///    This method must produce an expression with a Boolean result type that provides
        ///    the predicate logic.
        /// 
        /// A new DbQuantifierExpression that represents the Any operation. 
        ///  or  is null
        /// The expression produced by  is null 
        ///  
        ///     The expression produced by  does not have a Boolean result type.
        ///  
        public static DbFilterExpression Where(this DbExpression source, Func predicate)
        {
            DbExpression predicateExp;
            DbExpressionBinding input = ConvertToBinding(source, predicate, "predicate", out predicateExp); 
            return DbExpressionBuilder.Filter(input, predicateExp);
        } 
 
        /// 
        /// Creates a new  that computes the union of the left and right set arguments with duplicates removed. 
        /// 
        /// An expression that defines the left set argument.
        /// An expression that defines the right set argument.
        /// A new DbExpression that computes the union, without duplicates, of the the left and right arguments. 
        ///  or  is null
        /// No common collection result type with an equality-comparable element type exists between  and . 
        public static DbExpression Union(this DbExpression left, DbExpression right) 
        {
            return DbExpressionBuilder.Distinct(DbExpressionBuilder.UnionAll(left, right)); 
        }

        #endregion
 
        #region Internal Helper API - ideally these methods should be removed
 
        internal static DbNullExpression CreatePrimitiveNullExpression(PrimitiveTypeKind primitiveType) 
        {
            switch(primitiveType) 
            {
                case PrimitiveTypeKind.Binary:
                    return _binaryNull;
                case PrimitiveTypeKind.Boolean: 
                    return _boolNull;
                case PrimitiveTypeKind.Byte: 
                    return _byteNull; 
                case PrimitiveTypeKind.DateTime:
                    return _dateTimeNull; 
                case PrimitiveTypeKind.DateTimeOffset:
                    return _dateTimeOffsetNull;
                case PrimitiveTypeKind.Decimal:
                    return _decimalNull; 
                case PrimitiveTypeKind.Double:
                    return _doubleNull; 
                case PrimitiveTypeKind.Guid: 
                    return _guidNull;
                case PrimitiveTypeKind.Int16: 
                    return _int16Null;
                case PrimitiveTypeKind.Int32:
                    return _int32Null;
                case PrimitiveTypeKind.Int64: 
                    return _int64Null;
                case PrimitiveTypeKind.SByte: 
                    return _sbyteNull; 
                case PrimitiveTypeKind.Single:
                    return _singleNull; 
                case PrimitiveTypeKind.String:
                    return _stringNull;
                case PrimitiveTypeKind.Time:
                    return _timeNull; 

                default: 
                    throw EntityUtil.InvalidEnumerationValue(typeof(PrimitiveTypeKind), (int)primitiveType); 
            }
        } 

        internal static DbApplyExpression CreateApplyExpressionByKind(DbExpressionKind applyKind, DbExpressionBinding input, DbExpressionBinding apply)
        {
            Debug.Assert(DbExpressionKind.CrossApply == applyKind || DbExpressionKind.OuterApply == applyKind, "Invalid ApplyType"); 

            switch (applyKind) 
            { 
                case DbExpressionKind.CrossApply:
                    return CrossApply(input, apply); 

                case DbExpressionKind.OuterApply:
                    return OuterApply(input, apply);
 
                default:
                    throw EntityUtil.InvalidEnumerationValue(typeof(DbExpressionKind), (int)applyKind); 
            } 
        }
 
        internal static DbExpression CreateJoinExpressionByKind(DbExpressionKind joinKind, DbExpression joinCondition, DbExpressionBinding input1, DbExpressionBinding input2)
        {
            Debug.Assert(DbExpressionKind.CrossJoin == joinKind ||
                         DbExpressionKind.FullOuterJoin == joinKind || 
                         DbExpressionKind.InnerJoin == joinKind ||
                         DbExpressionKind.LeftOuterJoin == joinKind, 
                         "Invalid DbExpressionKind for CreateJoinExpressionByKind"); 

            if (DbExpressionKind.CrossJoin == joinKind) 
            {
                Debug.Assert(null == joinCondition, "Condition should not be specified for CrossJoin");
                return CrossJoin(new DbExpressionBinding[2] { input1, input2 });
            } 
            else
            { 
                Debug.Assert(joinCondition != null, "Condition must be specified for non-CrossJoin"); 

                switch (joinKind) 
                {
                    case DbExpressionKind.InnerJoin:
                        return InnerJoin(input1, input2, joinCondition);
 
                    case DbExpressionKind.LeftOuterJoin:
                        return LeftOuterJoin(input1, input2, joinCondition); 
 
                    case DbExpressionKind.FullOuterJoin:
                        return FullOuterJoin(input1, input2, joinCondition); 

                    default:
                        throw EntityUtil.InvalidEnumerationValue(typeof(DbExpressionKind), (int)joinKind);
                } 
            }
        } 
 
        /// 
        /// Used only by span rewriter, when a row could be specified as an argument 
        /// 
        internal static DbIsNullExpression CreateIsNullExpressionAllowingRowTypeArgument(DbExpression argument)
        {
            TypeUsage resultType = ArgumentValidation.ValidateIsNull(argument, true); 
            return new DbIsNullExpression(resultType, argument, true);
        } 
 
        /// 
        /// Creates a new  that converts a single-member set with a single property 
        /// into a singleton.  The result type of the created  equals the result type
        /// of the single property of the element of the argument.
        ///
        /// This method should only be used when the argument is of a collection type with 
        /// element of structured type with only one property.
        ///  
        /// An expression that specifies the input set. 
        /// A DbElementExpression that represents the conversion of the single-member set argument to a singleton.
        ///  is null 
        /// 
        ///      is associated with a different command tree,
        ///     or does not have a collection result type, or its element type is not a structured type
        ///     with only one property 
        /// 
        internal static DbElementExpression CreateElementExpressionUnwrapSingleProperty(DbExpression argument) 
        { 
            TypeUsage resultType = ArgumentValidation.ValidateElement(argument);
 
            // Change the result type of the element expression to the type of the
            // single property of the element of its operand.
            IList properties = TypeHelpers.GetProperties(resultType);
            if (properties == null || properties.Count != 1) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Element_InvalidArgumentForUnwrapSingleProperty, "arg"); 
            } 
            resultType = properties[0].TypeUsage;
            return new DbElementExpression(resultType, argument, true); 
        }

        /// 
        /// Creates a new  that describes how to satisfy the relationship 
        /// navigation operation from  to , which
        /// must be declared by the same relationship type. 
        /// DbRelatedEntityRefs are used in conjuction with  
        /// to construct Entity instances that are capable of resolving relationship navigation operations based on
        /// the provided DbRelatedEntityRefs without the need for additional navigation operations. 
        /// Note also that this factory method is not intended to be part of the public Command Tree API
        /// since its intent is to support Entity constructors in view definitions that express information about
        /// related Entities using the 'WITH RELATIONSHIPS' clause in eSQL.
        ///  
        /// The relationship end from which navigation takes place
        ///The relationship end to which navigation may be satisifed using the target entity ref 
        ///An expression that produces a reference to the target entity (and must therefore have a Ref result type) 
        internal static DbRelatedEntityRef CreateRelatedEntityRef(RelationshipEndMember sourceEnd, RelationshipEndMember targetEnd, DbExpression targetEntity)
        { 
            return new DbRelatedEntityRef(sourceEnd, targetEnd, targetEntity);
        }

        ///  
        /// Creates a new  that constructs an instance of an Entity type
        /// together with the specified information about Entities related to the newly constructed Entity by' 
        /// relationship navigations where the target end has multiplicity of at most one. 
        /// Note that this factory method is not intended to be part of the public Command Tree API since it
        /// its intent is to support Entity constructors in view definitions that express information about 
        /// related Entities using the 'WITH RELATIONSHIPS' clause in eSQL.
        /// 
        /// The type of the Entity instance that is being constructed
        /// Values for each (non-relationship) property of the Entity 
        /// A (possibly empty) list of s that describe Entities that are related to the constructed Entity by various relationship types.
        /// A new DbNewInstanceExpression that represents the construction of the Entity, and includes the specified related Entity information in the see  collection. 
        internal static DbNewInstanceExpression CreateNewEntityWithRelationshipsExpression(EntityType entityType, IList attributeValues, IList relationships) 
        {
            DbExpressionList validAttributes; 
            System.Collections.ObjectModel.ReadOnlyCollection validRelatedRefs;
            TypeUsage resultType = ArgumentValidation.ValidateNewEntityWithRelationships(entityType, attributeValues, relationships, out validAttributes, out validRelatedRefs);
            return new DbNewInstanceExpression(resultType, validAttributes, validRelatedRefs);
        } 

#if ENABLE_NESTAGGREGATE 
        ///  
        /// Creates a new  over the specified argument
        ///  
        /// The argument over which to perform the nest operation
        /// A new nest aggregate with a reference to the given argument.
        ///  is null
        ///  is associated with a different command tree 
        /*CQT_PUBLIC_API(*/internal/*)*/ NestAggregate CreateNestAggregate(Expression argument)
        { 
            return new NestAggregate(this, argument); 
        }
#endif 

#if METHOD_EXPRESSION
        /// 
        /// Creates a new  representing the invocation of the specified method on the given instance with the given arguments. 
        /// 
        /// The metadata for the method to invoke. 
        /// The invocation target. 
        /// The arguments to the method.
        /// A new MethodExpression that represents the method invocation. 
        /// 
        ///      or  is null,
        ///     or  is null or contains null
        ///  
        /// 
        ///      is not associated with this command tree's metadata workspace, 
        ///      is associated with a different command tree 
        ///     or has a result type that is not equal or promotable to the declaring type of the method,
        ///     or  contains an incorrect number of expressions, 
        ///     an expression with a result type that is not equal or promotable to the type of the corresponding
        ///     method parameter, or an expression that is associated with a different command tree.
        /// 
        /*CQT_PUBLIC_API(*/internal/*)*/ MethodExpression CreateInstanceMethodExpression(MethodMetadata methodInfo, Expression instance, IList args) 
        {
            if (methodInfo != null && methodInfo.IsStatic) 
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Factory_InstanceMethodRequired, "methodInfo");
            } 

            return new MethodExpression(this, methodInfo, args, instance);
        }
 
        /// 
        /// Creates a new  representing the invocation of the specified method with the given arguments. 
        ///  
        /// The metadata for the method to invoke.
        /// The arguments to the method. 
        /// A new MethodExpression that represents the method invocation.
        ///  is null, or  is null or contains null
        /// 
        ///      is not associated with this command tree's metadata workspace, 
        ///     or  contains an incorrect number of expressions,
        ///     an expression with a result type that is not equal or promotable to the type of the corresponding 
        ///     method parameter, or an expression that is associated with a different command tree. 
        /// 
        /*CQT_PUBLIC_API(*/internal/*)*/ MethodExpression CreateStaticMethodExpression(MethodMetadata methodInfo, IList args) 
        {
            if (methodInfo != null && !methodInfo.IsStatic)
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Factory_StaticMethodRequired, "methodInfo"); 
            }
 
            return new MethodExpression(this, methodInfo, args, null); 
        }
#endif 

        #endregion
    }
} 

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