ObjectQueryProvider.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 / ELinq / ObjectQueryProvider.cs / 1305376 / ObjectQueryProvider.cs

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

using System; 
using System.Collections.Generic;
using System.Data.Objects.Internal;
using System.Data.Metadata.Edm;
using System.Diagnostics; 
using System.Linq;
using System.Linq.Expressions; 
using System.Reflection; 

namespace System.Data.Objects.ELinq 
{
    /// 
    /// LINQ query provider implementation.
    ///  
    internal sealed class ObjectQueryProvider : IQueryProvider
    { 
        private readonly ObjectContext _context; 

        internal ObjectQueryProvider(ObjectContext context) 
        {
            Debug.Assert(null != context, "context must be given");
            _context = context;
        } 

        ///  
        /// Creates a new query instance using the given LINQ expresion. 
        /// The current query is used to produce the context for the new query, but none of its logic
        /// is used. 
        /// 
        /// Element type for query result.
        /// LINQ expression forming the query.
        /// ObjectQuery implementing the expression logic. 
        IQueryable IQueryProvider.CreateQuery(Expression expression)
        { 
            EntityUtil.CheckArgumentNull(expression, "expression"); 
            if (!typeof(IQueryable).IsAssignableFrom(expression.Type))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.ELinq_ExpressionMustBeIQueryable, "expression");
            }

            ObjectQuery query = CreateQuery(expression); 

            return query; 
        } 

        ///  
        /// Executes the given LINQ expression returning a single value, or null if the query yields
        /// no results. If the return type is unexpected, raises a cast exception.
        /// The current query is used to produce the context for the new query, but none of its logic
        /// is used. 
        /// 
        /// Type of returned value. 
        /// Expression to evaluate. 
        /// Single result from execution.
        S IQueryProvider.Execute(Expression expression) 
        {
            EntityUtil.CheckArgumentNull(expression, "expression");
            ObjectQuery query = CreateQuery(expression);
 
            return ExecuteSingle(query, expression);
        } 
 
        /// 
        /// Creates a new query instance using the given LINQ expresion. 
        /// The current query is used to produce the context for the new query, but none of its logic
        /// is used.
        /// 
        /// Expression forming the query. 
        /// ObjectQuery instance implementing the given expression.
        IQueryable IQueryProvider.CreateQuery(Expression expression) 
        { 
            EntityUtil.CheckArgumentNull(expression, "expression");
            if (!typeof(IQueryable).IsAssignableFrom(expression.Type)) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.ELinq_ExpressionMustBeIQueryable, "expression");
            }
 
            // Determine the type of the query instance by binding generic parameter in Query<>.Queryable
            // (based on element type of expression) 
            Type elementType = TypeSystem.GetElementType(expression.Type); 
            ObjectQuery query = CreateQuery(expression, elementType);
 
            return query;
        }

        ///  
        /// Executes the given LINQ expression returning a single value, or null if the query yields
        /// no results. 
        /// The current query is used to produce the context for the new query, but none of its logic 
        /// is used.
        ///  
        /// Expression to evaluate.
        /// Single result from execution.
        object IQueryProvider.Execute(Expression expression)
        { 
            EntityUtil.CheckArgumentNull(expression, "expression");
 
            ObjectQuery query = CreateQuery(expression, expression.Type); 
            IEnumerable objQuery = Enumerable.Cast(query);
            return ExecuteSingle(objQuery, expression); 
        }

        /// 
        /// Creates a new query from an expression. 
        /// 
        /// The element type of the query. 
        /// Expression forming the query. 
        /// A new ObjectQuery<S> instance.
        private ObjectQuery CreateQuery(Expression expression) 
        {
            ObjectQueryState query = new ELinqQueryState(typeof(S), _context, expression);
            return new ObjectQuery(query);
        } 

        ///  
        /// Provides an untyped method capable of creating a strong-typed ObjectQuery 
        /// (based on the  argument) and returning it as an
        /// instance of the untyped (in a generic sense) ObjectQuery base class. 
        /// 
        /// The LINQ expression that defines the new query
        /// The result type of the new ObjectQuery
        /// A new ObjectQuery<ofType>, as an instance of ObjectQuery 
        private ObjectQuery CreateQuery(Expression expression, Type ofType)
        { 
            ObjectQueryState query = new ELinqQueryState(ofType, _context, expression); 
            return query.CreateQuery();
        } 

        #region Internal Utility API

        ///  
        /// Uses an expression-specific 'materialization' function to produce
        /// a singleton result from an IEnumerable query result. The function 
        /// used depends on the semantics required by the expression that is 
        /// the root of the query. First,FirstOrDefault and SingleOrDefault are
        /// currently handled as special cases, and the default behavior is to 
        /// use the Enumerable.Single materialization pattern.
        /// 
        /// The expected result type and the required element type of the IEnumerable collection
        /// The query result set 
        /// The expression that is the root of the LINQ query expression tree
        /// An instance of TResult if evaluation of the expression-specific singleton-producing function is successful 
        internal static TResult ExecuteSingle(IEnumerable query, Expression queryRoot) 
        {
            return GetElementFunction(queryRoot)(query); 
        }

        private static Func, TResult> GetElementFunction(Expression queryRoot)
        { 
            SequenceMethod seqMethod;
            if (ReflectionUtil.TryIdentifySequenceMethod(queryRoot, true /*unwrapLambdas*/, out seqMethod)) 
            { 
                switch (seqMethod)
                { 
                    case SequenceMethod.First:
                    case SequenceMethod.FirstPredicate:
                            return (sequence) => { return Enumerable.First(sequence); };
 
                    case SequenceMethod.FirstOrDefault:
                    case SequenceMethod.FirstOrDefaultPredicate: 
                            return (sequence) => { return Enumerable.FirstOrDefault(sequence); }; 

                    case SequenceMethod.SingleOrDefault: 
                    case SequenceMethod.SingleOrDefaultPredicate:
                            return (sequence) => { return Enumerable.SingleOrDefault(sequence); };
                }
            } 

            return (sequence) => { return Enumerable.Single(sequence); }; 
        } 

        #endregion 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System; 
using System.Collections.Generic;
using System.Data.Objects.Internal;
using System.Data.Metadata.Edm;
using System.Diagnostics; 
using System.Linq;
using System.Linq.Expressions; 
using System.Reflection; 

namespace System.Data.Objects.ELinq 
{
    /// 
    /// LINQ query provider implementation.
    ///  
    internal sealed class ObjectQueryProvider : IQueryProvider
    { 
        private readonly ObjectContext _context; 

        internal ObjectQueryProvider(ObjectContext context) 
        {
            Debug.Assert(null != context, "context must be given");
            _context = context;
        } 

        ///  
        /// Creates a new query instance using the given LINQ expresion. 
        /// The current query is used to produce the context for the new query, but none of its logic
        /// is used. 
        /// 
        /// Element type for query result.
        /// LINQ expression forming the query.
        /// ObjectQuery implementing the expression logic. 
        IQueryable IQueryProvider.CreateQuery(Expression expression)
        { 
            EntityUtil.CheckArgumentNull(expression, "expression"); 
            if (!typeof(IQueryable).IsAssignableFrom(expression.Type))
            { 
                throw EntityUtil.Argument(System.Data.Entity.Strings.ELinq_ExpressionMustBeIQueryable, "expression");
            }

            ObjectQuery query = CreateQuery(expression); 

            return query; 
        } 

        ///  
        /// Executes the given LINQ expression returning a single value, or null if the query yields
        /// no results. If the return type is unexpected, raises a cast exception.
        /// The current query is used to produce the context for the new query, but none of its logic
        /// is used. 
        /// 
        /// Type of returned value. 
        /// Expression to evaluate. 
        /// Single result from execution.
        S IQueryProvider.Execute(Expression expression) 
        {
            EntityUtil.CheckArgumentNull(expression, "expression");
            ObjectQuery query = CreateQuery(expression);
 
            return ExecuteSingle(query, expression);
        } 
 
        /// 
        /// Creates a new query instance using the given LINQ expresion. 
        /// The current query is used to produce the context for the new query, but none of its logic
        /// is used.
        /// 
        /// Expression forming the query. 
        /// ObjectQuery instance implementing the given expression.
        IQueryable IQueryProvider.CreateQuery(Expression expression) 
        { 
            EntityUtil.CheckArgumentNull(expression, "expression");
            if (!typeof(IQueryable).IsAssignableFrom(expression.Type)) 
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.ELinq_ExpressionMustBeIQueryable, "expression");
            }
 
            // Determine the type of the query instance by binding generic parameter in Query<>.Queryable
            // (based on element type of expression) 
            Type elementType = TypeSystem.GetElementType(expression.Type); 
            ObjectQuery query = CreateQuery(expression, elementType);
 
            return query;
        }

        ///  
        /// Executes the given LINQ expression returning a single value, or null if the query yields
        /// no results. 
        /// The current query is used to produce the context for the new query, but none of its logic 
        /// is used.
        ///  
        /// Expression to evaluate.
        /// Single result from execution.
        object IQueryProvider.Execute(Expression expression)
        { 
            EntityUtil.CheckArgumentNull(expression, "expression");
 
            ObjectQuery query = CreateQuery(expression, expression.Type); 
            IEnumerable objQuery = Enumerable.Cast(query);
            return ExecuteSingle(objQuery, expression); 
        }

        /// 
        /// Creates a new query from an expression. 
        /// 
        /// The element type of the query. 
        /// Expression forming the query. 
        /// A new ObjectQuery<S> instance.
        private ObjectQuery CreateQuery(Expression expression) 
        {
            ObjectQueryState query = new ELinqQueryState(typeof(S), _context, expression);
            return new ObjectQuery(query);
        } 

        ///  
        /// Provides an untyped method capable of creating a strong-typed ObjectQuery 
        /// (based on the  argument) and returning it as an
        /// instance of the untyped (in a generic sense) ObjectQuery base class. 
        /// 
        /// The LINQ expression that defines the new query
        /// The result type of the new ObjectQuery
        /// A new ObjectQuery<ofType>, as an instance of ObjectQuery 
        private ObjectQuery CreateQuery(Expression expression, Type ofType)
        { 
            ObjectQueryState query = new ELinqQueryState(ofType, _context, expression); 
            return query.CreateQuery();
        } 

        #region Internal Utility API

        ///  
        /// Uses an expression-specific 'materialization' function to produce
        /// a singleton result from an IEnumerable query result. The function 
        /// used depends on the semantics required by the expression that is 
        /// the root of the query. First,FirstOrDefault and SingleOrDefault are
        /// currently handled as special cases, and the default behavior is to 
        /// use the Enumerable.Single materialization pattern.
        /// 
        /// The expected result type and the required element type of the IEnumerable collection
        /// The query result set 
        /// The expression that is the root of the LINQ query expression tree
        /// An instance of TResult if evaluation of the expression-specific singleton-producing function is successful 
        internal static TResult ExecuteSingle(IEnumerable query, Expression queryRoot) 
        {
            return GetElementFunction(queryRoot)(query); 
        }

        private static Func, TResult> GetElementFunction(Expression queryRoot)
        { 
            SequenceMethod seqMethod;
            if (ReflectionUtil.TryIdentifySequenceMethod(queryRoot, true /*unwrapLambdas*/, out seqMethod)) 
            { 
                switch (seqMethod)
                { 
                    case SequenceMethod.First:
                    case SequenceMethod.FirstPredicate:
                            return (sequence) => { return Enumerable.First(sequence); };
 
                    case SequenceMethod.FirstOrDefault:
                    case SequenceMethod.FirstOrDefaultPredicate: 
                            return (sequence) => { return Enumerable.FirstOrDefault(sequence); }; 

                    case SequenceMethod.SingleOrDefault: 
                    case SequenceMethod.SingleOrDefaultPredicate:
                            return (sequence) => { return Enumerable.SingleOrDefault(sequence); };
                }
            } 

            return (sequence) => { return Enumerable.Single(sequence); }; 
        } 

        #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