ObjectQueryState.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Objects / Internal / ObjectQueryState.cs / 1599186 / ObjectQueryState.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....]
//--------------------------------------------------------------------- 
 
namespace System.Data.Objects.Internal
{ 
    using System;
    using System.Collections.Generic;
    using System.Data.Common;
    using System.Data.Common.CommandTrees; 
    using System.Data.Common.EntitySql;
    using System.Data.EntityClient; 
    using System.Data.Metadata.Edm; 
    using System.Data.Objects;
    using System.Data.Objects.DataClasses; 
    using System.Diagnostics;
    using System.Globalization;
    using System.Reflection;
    using System.Data.Objects.ELinq; 
    using System.Runtime.CompilerServices;
 
    ///  
    ///   An instance of a class derived from ObjectQueryState is used to model every instance of .
    ///   A different ObjectQueryState-derived class is used depending on whether the ObjectQuery is an Entity SQL, 
    ///   Linq to Entities, or compiled Linq to Entities query.
    /// 
    internal abstract class ObjectQueryState
    { 
        /// 
        ///   The  that should be used in the absence of an explicitly specified 
        ///   or user-specified merge option or a merge option inferred from the query definition itself. 
        /// 
        internal static readonly MergeOption DefaultMergeOption = MergeOption.AppendOnly; 

        /// 
        ///   The context of the ObjectQuery
        ///  
        private readonly ObjectContext _context;
 
        ///  
        ///   The element type of this query, as a CLR type
        ///  
        private readonly Type _elementType;

        /// 
        ///   The collection of parameters associated with the ObjectQuery 
        /// 
        private ObjectParameterCollection _parameters; 
 
        /// 
        ///   The full-span specification 
        /// 
        private Span _span;

        ///  
        ///   The user-specified default merge option
        ///  
        private MergeOption? _userMergeOption; 

        ///  
        ///   Indicates whether query caching is enabled for the implemented ObjectQuery.
        /// 
        private bool _cachingEnabled;
 
        /// 
        ///   Optionally used by derived classes to record the most recently used . 
        ///  
        protected ObjectQueryExecutionPlan _cachedPlan;
 

        /// 
        ///   Constructs a new ObjectQueryImplementation that uses the specified context and parameters collection.
        ///  
        /// 
        ///   The ObjectContext to which the implemented ObjectQuery belongs 
        ///  
        protected ObjectQueryState(Type elementType, ObjectContext context, ObjectParameterCollection parameters, Span span)
        { 
            // Validate the element type
            EntityUtil.CheckArgumentNull(elementType, "elementType");

            // Validate the context 
            EntityUtil.CheckArgumentNull(context, "context");
 
            // Parameters and Span are specifically allowed to be null 

            this._elementType = elementType; 
            this._context = context;
            this._span = span;
            this._parameters = parameters;
        } 

        ///  
        ///   Gets the element type - the type of each result item - for this query as a CLR type instance. 
        /// 
        internal Type ElementType { get { return _elementType; } } 

        /// 
        ///   Gets the ObjectContext with which the implemented ObjectQuery is associated
        ///  
        internal ObjectContext ObjectContext { get { return _context; } }
 
        ///  
        ///   Gets the collection of parameters associated with the implemented ObjectQuery. May be null.
        ///   Call  if a guaranteed non-null collection is required. 
        /// 
        internal ObjectParameterCollection Parameters
        {
            get { return _parameters; } 
        }
 
        internal ObjectParameterCollection EnsureParameters() 
        {
            if (_parameters == null) 
            {
                _parameters = new ObjectParameterCollection(ObjectContext.Perspective);
                if (this._cachedPlan != null)
                { 
                    _parameters.SetReadOnly(true);
                } 
            } 

            return _parameters; 
        }

        /// 
        ///   Gets the Span specification associated with the implemented ObjectQuery. May be null. 
        /// 
        internal Span Span 
        { 
            get { return _span; }
        } 

        /// 
        ///   The merge option that this query considers currently 'in effect'. This may be a merge option set via the ObjectQuery.MergeOption
        ///   property, or the merge option that applies to the currently cached execution plan, if any, or the global default merge option. 
        /// 
        internal MergeOption EffectiveMergeOption 
        { 
            get
            { 
                if (_userMergeOption.HasValue)
                {
                    return _userMergeOption.Value;
                } 

                ObjectQueryExecutionPlan plan = this._cachedPlan; 
                if (plan != null) 
                {
                    return plan.MergeOption; 
                }

                return ObjectQueryState.DefaultMergeOption;
            } 
        }
 
        ///  
        ///   Gets or sets a value indicating which  should be used when preparing this query for execution via
        ///    if no option is explicitly specified - for example during foreach-style enumeration. 
        ///    sets this property on its underlying query state instance.
        /// 
        internal MergeOption? UserSpecifiedMergeOption
        { 
            get { return _userMergeOption; }
            set { _userMergeOption = value; } 
        } 

        ///  
        ///   Gets or sets a value indicating whether or not query caching is enabled for the imlemented ObjectQuery.
        /// 
        internal bool PlanCachingEnabled
        { 
            get { return _cachingEnabled; }
            set { _cachingEnabled = value; } 
        } 

        ///  
        ///   Gets the result type - not just the element type - for this query as an EDM Type usage instance.
        /// 
        internal TypeUsage ResultType
        { 
            get
            { 
                ObjectQueryExecutionPlan plan = this._cachedPlan; 
                if (plan != null)
                { 
                    return plan.ResultType;
                }
                else
                { 
                    return this.GetResultType();
                } 
            } 
        }
 
        /// 
        ///   Sets the values the  and  properties on
        ///    to match the values of the corresponding properties on this instance.
        ///  
        /// The query state to which this instances settings should be applied.
        internal void ApplySettingsTo(ObjectQueryState other) 
        { 
            other.PlanCachingEnabled = this.PlanCachingEnabled;
            other.UserSpecifiedMergeOption = this.UserSpecifiedMergeOption; 

            // _cachedPlan is intentionally not copied over - since the parameters of 'other' would have to be locked as
            // soon as its execution plan was set, and that may not be appropriate at the time ApplySettingsTo is called.
        } 

        ///  
        ///   Must return true and set  to a valid value 
        ///   if command text is available for this query; must return false otherwise.
        ///   Implementations of this method must not throw exceptions. 
        /// 
        /// The command text of this query, if available.
        /// true if command text is available for this query and was successfully retrieved; otherwise false.
        internal abstract bool TryGetCommandText(out string commandText); 

        ///  
        ///   Must return true and set  to a valid value if a 
        ///   LINQ Expression is available for this query; must return false otherwise.
        ///   Implementations of this method must not throw exceptions. 
        /// 
        /// The LINQ Expression that defines this query, if available.
        /// true if an Expression is available for this query and was successfully retrieved; otherwise false.
        internal abstract bool TryGetExpression(out System.Linq.Expressions.Expression expression); 

        ///  
        ///   Retrieves an  that can be used to retrieve the results of this query using the specified merge option. 
        ///   If  is null, an appropriate default value will be used.
        ///  
        /// The merge option which should be supported by the returned execution plan
        /// an execution plan capable of retrieving the results of this query using the specified merge option
        internal abstract ObjectQueryExecutionPlan GetExecutionPlan(MergeOption? forMergeOption);
 
        /// 
        ///   Must returns a new ObjectQueryState instance that is a duplicate of this instance and additionally contains the specified Include path in its . 
        ///  
        /// The element type of the source query on which Include was called
        /// The source query on which Include was called 
        /// The new Include path to add
        /// Must returns an ObjectQueryState that is a duplicate of this instance and additionally contains the specified Include path
        internal abstract ObjectQueryState Include(ObjectQuery sourceQuery, string includePath);
 
        /// 
        ///   Retrieves the result type of the query in terms of C-Space metadata. This method is called once, on-demand, if a call 
        ///   to  cannot be satisfied using cached type metadata or a currently cached execution plan. 
        /// 
        ///  
        ///   Must return a  that describes the result typeof this query in terms of C-Space metadata
        /// 
        protected abstract TypeUsage GetResultType();
 
        /// 
        ///   Helper method to return the first non-null merge option from the specified nullable merge options, 
        ///   or the  if the value of all specified nullable merge options is null. 
        /// 
        /// The available nullable merge option values, in order of decreasing preference 
        /// the first non-null merge option; or the default merge option if the value of all  is null
        protected static MergeOption EnsureMergeOption(params MergeOption?[] preferredMergeOptions)
        {
            foreach (MergeOption? preferred in preferredMergeOptions) 
            {
                if (preferred.HasValue) 
                { 
                    return preferred.Value;
                } 
            }

            return ObjectQueryState.DefaultMergeOption;
        } 

        ///  
        ///   Helper method to return the first non-null merge option from the specified nullable merge options. 
        /// 
        /// The available nullable merge option values, in order of decreasing preference 
        /// the first non-null merge option; or null if the value of all  is null
        protected static MergeOption? GetMergeOption(params MergeOption?[] preferredMergeOptions)
        {
            foreach (MergeOption? preferred in preferredMergeOptions) 
            {
                if (preferred.HasValue) 
                { 
                    return preferred.Value;
                } 
            }

            return null;
        } 

        ///  
        /// Helper method to create a new ObjectQuery based on this query state instance. 
        /// 
        /// A new  - typed as  
        [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
        internal ObjectQuery CreateQuery()
        {
            MethodInfo createMethod = typeof(ObjectQueryState).GetMethod("CreateObjectQuery", BindingFlags.Static | BindingFlags.Public); 
            Debug.Assert(createMethod != null, "Unable to retrieve ObjectQueryState.CreateObjectQuery<> method?");
 
            createMethod = createMethod.MakeGenericMethod(this._elementType); 
            return (ObjectQuery)createMethod.Invoke(null, new object[] { this } );
        } 

        /// 
        /// Helper method used to create an ObjectQuery based on an underlying ObjectQueryState instance.
        /// Although not called directly, this method must be public to be reliably callable from  using reflection. 
        /// 
        /// The required element type of the new ObjectQuery 
        /// The underlying ObjectQueryState instance that should back the returned ObjectQuery 
        /// A new ObjectQuery based on the specified query state, with the specified element type
        public static ObjectQuery CreateObjectQuery(ObjectQueryState queryState) 
        {
            Debug.Assert(queryState != null, "Query state is required");
            Debug.Assert(typeof(TResultType) == queryState.ElementType, "Element type mismatch");
 
            return new ObjectQuery(queryState);
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....]
//--------------------------------------------------------------------- 
 
namespace System.Data.Objects.Internal
{ 
    using System;
    using System.Collections.Generic;
    using System.Data.Common;
    using System.Data.Common.CommandTrees; 
    using System.Data.Common.EntitySql;
    using System.Data.EntityClient; 
    using System.Data.Metadata.Edm; 
    using System.Data.Objects;
    using System.Data.Objects.DataClasses; 
    using System.Diagnostics;
    using System.Globalization;
    using System.Reflection;
    using System.Data.Objects.ELinq; 
    using System.Runtime.CompilerServices;
 
    ///  
    ///   An instance of a class derived from ObjectQueryState is used to model every instance of .
    ///   A different ObjectQueryState-derived class is used depending on whether the ObjectQuery is an Entity SQL, 
    ///   Linq to Entities, or compiled Linq to Entities query.
    /// 
    internal abstract class ObjectQueryState
    { 
        /// 
        ///   The  that should be used in the absence of an explicitly specified 
        ///   or user-specified merge option or a merge option inferred from the query definition itself. 
        /// 
        internal static readonly MergeOption DefaultMergeOption = MergeOption.AppendOnly; 

        /// 
        ///   The context of the ObjectQuery
        ///  
        private readonly ObjectContext _context;
 
        ///  
        ///   The element type of this query, as a CLR type
        ///  
        private readonly Type _elementType;

        /// 
        ///   The collection of parameters associated with the ObjectQuery 
        /// 
        private ObjectParameterCollection _parameters; 
 
        /// 
        ///   The full-span specification 
        /// 
        private Span _span;

        ///  
        ///   The user-specified default merge option
        ///  
        private MergeOption? _userMergeOption; 

        ///  
        ///   Indicates whether query caching is enabled for the implemented ObjectQuery.
        /// 
        private bool _cachingEnabled;
 
        /// 
        ///   Optionally used by derived classes to record the most recently used . 
        ///  
        protected ObjectQueryExecutionPlan _cachedPlan;
 

        /// 
        ///   Constructs a new ObjectQueryImplementation that uses the specified context and parameters collection.
        ///  
        /// 
        ///   The ObjectContext to which the implemented ObjectQuery belongs 
        ///  
        protected ObjectQueryState(Type elementType, ObjectContext context, ObjectParameterCollection parameters, Span span)
        { 
            // Validate the element type
            EntityUtil.CheckArgumentNull(elementType, "elementType");

            // Validate the context 
            EntityUtil.CheckArgumentNull(context, "context");
 
            // Parameters and Span are specifically allowed to be null 

            this._elementType = elementType; 
            this._context = context;
            this._span = span;
            this._parameters = parameters;
        } 

        ///  
        ///   Gets the element type - the type of each result item - for this query as a CLR type instance. 
        /// 
        internal Type ElementType { get { return _elementType; } } 

        /// 
        ///   Gets the ObjectContext with which the implemented ObjectQuery is associated
        ///  
        internal ObjectContext ObjectContext { get { return _context; } }
 
        ///  
        ///   Gets the collection of parameters associated with the implemented ObjectQuery. May be null.
        ///   Call  if a guaranteed non-null collection is required. 
        /// 
        internal ObjectParameterCollection Parameters
        {
            get { return _parameters; } 
        }
 
        internal ObjectParameterCollection EnsureParameters() 
        {
            if (_parameters == null) 
            {
                _parameters = new ObjectParameterCollection(ObjectContext.Perspective);
                if (this._cachedPlan != null)
                { 
                    _parameters.SetReadOnly(true);
                } 
            } 

            return _parameters; 
        }

        /// 
        ///   Gets the Span specification associated with the implemented ObjectQuery. May be null. 
        /// 
        internal Span Span 
        { 
            get { return _span; }
        } 

        /// 
        ///   The merge option that this query considers currently 'in effect'. This may be a merge option set via the ObjectQuery.MergeOption
        ///   property, or the merge option that applies to the currently cached execution plan, if any, or the global default merge option. 
        /// 
        internal MergeOption EffectiveMergeOption 
        { 
            get
            { 
                if (_userMergeOption.HasValue)
                {
                    return _userMergeOption.Value;
                } 

                ObjectQueryExecutionPlan plan = this._cachedPlan; 
                if (plan != null) 
                {
                    return plan.MergeOption; 
                }

                return ObjectQueryState.DefaultMergeOption;
            } 
        }
 
        ///  
        ///   Gets or sets a value indicating which  should be used when preparing this query for execution via
        ///    if no option is explicitly specified - for example during foreach-style enumeration. 
        ///    sets this property on its underlying query state instance.
        /// 
        internal MergeOption? UserSpecifiedMergeOption
        { 
            get { return _userMergeOption; }
            set { _userMergeOption = value; } 
        } 

        ///  
        ///   Gets or sets a value indicating whether or not query caching is enabled for the imlemented ObjectQuery.
        /// 
        internal bool PlanCachingEnabled
        { 
            get { return _cachingEnabled; }
            set { _cachingEnabled = value; } 
        } 

        ///  
        ///   Gets the result type - not just the element type - for this query as an EDM Type usage instance.
        /// 
        internal TypeUsage ResultType
        { 
            get
            { 
                ObjectQueryExecutionPlan plan = this._cachedPlan; 
                if (plan != null)
                { 
                    return plan.ResultType;
                }
                else
                { 
                    return this.GetResultType();
                } 
            } 
        }
 
        /// 
        ///   Sets the values the  and  properties on
        ///    to match the values of the corresponding properties on this instance.
        ///  
        /// The query state to which this instances settings should be applied.
        internal void ApplySettingsTo(ObjectQueryState other) 
        { 
            other.PlanCachingEnabled = this.PlanCachingEnabled;
            other.UserSpecifiedMergeOption = this.UserSpecifiedMergeOption; 

            // _cachedPlan is intentionally not copied over - since the parameters of 'other' would have to be locked as
            // soon as its execution plan was set, and that may not be appropriate at the time ApplySettingsTo is called.
        } 

        ///  
        ///   Must return true and set  to a valid value 
        ///   if command text is available for this query; must return false otherwise.
        ///   Implementations of this method must not throw exceptions. 
        /// 
        /// The command text of this query, if available.
        /// true if command text is available for this query and was successfully retrieved; otherwise false.
        internal abstract bool TryGetCommandText(out string commandText); 

        ///  
        ///   Must return true and set  to a valid value if a 
        ///   LINQ Expression is available for this query; must return false otherwise.
        ///   Implementations of this method must not throw exceptions. 
        /// 
        /// The LINQ Expression that defines this query, if available.
        /// true if an Expression is available for this query and was successfully retrieved; otherwise false.
        internal abstract bool TryGetExpression(out System.Linq.Expressions.Expression expression); 

        ///  
        ///   Retrieves an  that can be used to retrieve the results of this query using the specified merge option. 
        ///   If  is null, an appropriate default value will be used.
        ///  
        /// The merge option which should be supported by the returned execution plan
        /// an execution plan capable of retrieving the results of this query using the specified merge option
        internal abstract ObjectQueryExecutionPlan GetExecutionPlan(MergeOption? forMergeOption);
 
        /// 
        ///   Must returns a new ObjectQueryState instance that is a duplicate of this instance and additionally contains the specified Include path in its . 
        ///  
        /// The element type of the source query on which Include was called
        /// The source query on which Include was called 
        /// The new Include path to add
        /// Must returns an ObjectQueryState that is a duplicate of this instance and additionally contains the specified Include path
        internal abstract ObjectQueryState Include(ObjectQuery sourceQuery, string includePath);
 
        /// 
        ///   Retrieves the result type of the query in terms of C-Space metadata. This method is called once, on-demand, if a call 
        ///   to  cannot be satisfied using cached type metadata or a currently cached execution plan. 
        /// 
        ///  
        ///   Must return a  that describes the result typeof this query in terms of C-Space metadata
        /// 
        protected abstract TypeUsage GetResultType();
 
        /// 
        ///   Helper method to return the first non-null merge option from the specified nullable merge options, 
        ///   or the  if the value of all specified nullable merge options is null. 
        /// 
        /// The available nullable merge option values, in order of decreasing preference 
        /// the first non-null merge option; or the default merge option if the value of all  is null
        protected static MergeOption EnsureMergeOption(params MergeOption?[] preferredMergeOptions)
        {
            foreach (MergeOption? preferred in preferredMergeOptions) 
            {
                if (preferred.HasValue) 
                { 
                    return preferred.Value;
                } 
            }

            return ObjectQueryState.DefaultMergeOption;
        } 

        ///  
        ///   Helper method to return the first non-null merge option from the specified nullable merge options. 
        /// 
        /// The available nullable merge option values, in order of decreasing preference 
        /// the first non-null merge option; or null if the value of all  is null
        protected static MergeOption? GetMergeOption(params MergeOption?[] preferredMergeOptions)
        {
            foreach (MergeOption? preferred in preferredMergeOptions) 
            {
                if (preferred.HasValue) 
                { 
                    return preferred.Value;
                } 
            }

            return null;
        } 

        ///  
        /// Helper method to create a new ObjectQuery based on this query state instance. 
        /// 
        /// A new  - typed as  
        [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
        internal ObjectQuery CreateQuery()
        {
            MethodInfo createMethod = typeof(ObjectQueryState).GetMethod("CreateObjectQuery", BindingFlags.Static | BindingFlags.Public); 
            Debug.Assert(createMethod != null, "Unable to retrieve ObjectQueryState.CreateObjectQuery<> method?");
 
            createMethod = createMethod.MakeGenericMethod(this._elementType); 
            return (ObjectQuery)createMethod.Invoke(null, new object[] { this } );
        } 

        /// 
        /// Helper method used to create an ObjectQuery based on an underlying ObjectQueryState instance.
        /// Although not called directly, this method must be public to be reliably callable from  using reflection. 
        /// 
        /// The required element type of the new ObjectQuery 
        /// The underlying ObjectQueryState instance that should back the returned ObjectQuery 
        /// A new ObjectQuery based on the specified query state, with the specified element type
        public static ObjectQuery CreateObjectQuery(ObjectQueryState queryState) 
        {
            Debug.Assert(queryState != null, "Query state is required");
            Debug.Assert(typeof(TResultType) == queryState.ElementType, "Element type mismatch");
 
            return new ObjectQuery(queryState);
        } 
    } 
}

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