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