// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. namespace System.Data.Entity.Infrastructure { using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data.Entity.Internal.Linq; using System.Data.Entity.Resources; using System.Data.Entity.Utilities; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Linq.Expressions; /// /// Represents a LINQ to Entities query against a DbContext. /// /// The type of entity to query for. [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Justification = "Name is intentional")] public class DbQuery : IOrderedQueryable, IListSource, IInternalQueryAdapter #if !NET40 , IDbAsyncEnumerable #endif { #region Fields and constructors // Handles the underlying ObjectQuery that backs the query. private readonly IInternalQuery _internalQuery; private IQueryProvider _provider; /// /// Creates a new query that will be backed by the given internal query object. /// /// The backing query. internal DbQuery(IInternalQuery internalQuery) { DebugCheck.NotNull(internalQuery); _internalQuery = internalQuery; } #endregion #region Include /// /// Specifies the related objects to include in the query results. /// /// /// Paths are all-inclusive. For example, if an include call indicates Include("Orders.OrderLines"), not only will /// OrderLines be included, but also Orders. When you call the Include method, the query path is only valid on /// the returned instance of the DbQuery /// /// . Other instances of DbQuery /// /// and the object context itself are not affected. /// Because the Include method returns the query object, you can call this method multiple times on an DbQuery /// /// to /// specify multiple paths for the query. /// /// The dot-separated list of related objects to return in the query results. /// /// A new with the defined query path. /// public DbQuery Include(string path) { Check.NotEmpty(path, "path"); return new DbQuery(_internalQuery.Include(path)); } #endregion #region AsNoTracking /// /// Returns a new query where the entities returned will not be cached in the . /// /// A new query with NoTracking applied. public DbQuery AsNoTracking() { return new DbQuery(_internalQuery.AsNoTracking()); } #endregion #region AsStreaming /// /// Returns a new query that will stream the results instead of buffering. /// /// A new query with AsStreaming applied. public DbQuery AsStreaming() { return new DbQuery(_internalQuery.AsStreaming()); } #endregion #region Data binding /// /// Returns false. /// /// /// false . /// [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")] bool IListSource.ContainsListCollection { get { return false; } } /// /// Throws an exception indicating that binding directly to a store query is not supported. /// Instead populate a DbSet with data, for example by using the Load extension method, and /// then bind to local data. For WPF bind to DbSet.Local. For Windows Forms bind to /// DbSet.Local.ToBindingList(). /// /// Never returns; always throws. [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")] IList IListSource.GetList() { throw Error.DbQuery_BindingToDbQueryNotSupported(); } #endregion #region IEnumerable /// /// Returns an which when enumerated will execute the query against the database. /// /// The query results. [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")] IEnumerator IEnumerable.GetEnumerator() { return _internalQuery.GetEnumerator(); } /// /// Returns an which when enumerated will execute the query against the database. /// /// The query results. [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")] IEnumerator IEnumerable.GetEnumerator() { return _internalQuery.GetEnumerator(); } #endregion #region IDbAsyncEnumerable #if !NET40 /// /// Returns an which when enumerated will execute the query against the database. /// /// The query results. [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")] IDbAsyncEnumerator IDbAsyncEnumerable.GetAsyncEnumerator() { return _internalQuery.GetAsyncEnumerator(); } /// /// Returns an which when enumerated will execute the query against the database. /// /// The query results. [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")] IDbAsyncEnumerator IDbAsyncEnumerable.GetAsyncEnumerator() { return _internalQuery.GetAsyncEnumerator(); } #endif #endregion #region IQueryable /// /// The IQueryable element type. /// [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")] Type IQueryable.ElementType { get { return _internalQuery.ElementType; } } /// /// The IQueryable LINQ Expression. /// [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")] Expression IQueryable.Expression { get { return _internalQuery.Expression; } } /// /// The IQueryable provider. /// [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")] IQueryProvider IQueryable.Provider { get { return _provider ?? (_provider = new DbQueryProvider( _internalQuery.InternalContext, _internalQuery.ObjectQueryProvider)); } } #endregion #region Internal query /// /// The internal query object that is backing this DbQuery /// IInternalQuery IInternalQueryAdapter.InternalQuery { get { return _internalQuery; } } /// /// The internal query object that is backing this DbQuery /// internal IInternalQuery InternalQuery { get { return _internalQuery; } } #endregion #region ToString /// /// Returns a representation of the underlying query. /// /// The query string. public override string ToString() { return _internalQuery.ToString(); } #endregion #region Conversion to non-generic /// /// Returns a new instance of the non-generic class for this query. /// /// A non-generic version. [SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Justification = "Intentionally just implicit to reduce API clutter.")] public static implicit operator DbQuery(DbQuery entry) { return new InternalDbQuery(entry._internalQuery); } #endregion #region Hidden Object methods [EditorBrowsable(EditorBrowsableState.Never)] public override bool Equals(object obj) { return base.Equals(obj); } [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { return base.GetHashCode(); } [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")] [EditorBrowsable(EditorBrowsableState.Never)] public new Type GetType() { return base.GetType(); } #endregion } }