// 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.Generic; using System.Data.Entity.Internal; using System.Data.Entity.Utilities; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading; using System.Threading.Tasks; /// /// Instances of this class are returned from the Collection method of /// and allow operations such as loading to /// be performed on the an entity's collection navigation properties. /// /// The type of the entity to which this property belongs. /// The type of the element in the collection of entities. public class DbCollectionEntry : DbMemberEntry> where TEntity : class { #region Fields and constructors private readonly InternalCollectionEntry _internalCollectionEntry; /// /// Creates a from information in the given /// /// . /// Use this method in preference to the constructor since it may potentially create a subclass depending on /// the type of member represented by the InternalCollectionEntry instance. /// /// The internal collection entry. /// The new entry. internal static DbCollectionEntry Create(InternalCollectionEntry internalCollectionEntry) { DebugCheck.NotNull(internalCollectionEntry); // Note that the implementation of this Create method is different than for the other DbMemberEntry classes. // This is because the DbMemberEntry is defined in terms of the ICollection while this class // is defined in terms of just TElement. This means that we can't just call the CreateDbMemberEntry factory // method on InternalMemberEntry. Instead we call the special factory method on InternalCollectionEntry. return internalCollectionEntry.CreateDbCollectionEntry(); } /// /// Initializes a new instance of the class. /// /// The internal entry. internal DbCollectionEntry(InternalCollectionEntry internalCollectionEntry) { DebugCheck.NotNull(internalCollectionEntry); _internalCollectionEntry = internalCollectionEntry; } #endregion #region Name /// /// Gets the property name. /// /// The property name. public override string Name { get { return _internalCollectionEntry.Name; } } #endregion #region Current values /// /// Gets or sets the current value of the navigation property. The current value is /// the entity that the navigation property references. /// /// The current value. [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public override ICollection CurrentValue { get { return (ICollection)_internalCollectionEntry.CurrentValue; } set { _internalCollectionEntry.CurrentValue = value; } } #endregion #region Loading /// /// Loads the collection of entities from the database. /// Note that entities that already exist in the context are not overwritten with values from the database. /// public void Load() { _internalCollectionEntry.Load(); } #if !NET40 /// /// An asynchronous version of Load, which /// loads the entity from the database. /// Note that if the entity already exists in the context, then it will not overwritten with values from the database. /// /// A Task representing the asynchronous operation. public Task LoadAsync() { return LoadAsync(CancellationToken.None); } /// /// An asynchronous version of Load, which /// loads the entity from the database. /// Note that if the entity already exists in the context, then it will not overwritten with values from the database. /// /// The token to monitor for cancellation requests. /// A Task representing the asynchronous operation. public Task LoadAsync(CancellationToken cancellationToken) { return _internalCollectionEntry.LoadAsync(cancellationToken); } #endif /// /// Gets a value indicating whether the collection of entities has been loaded from the database. /// /// /// true if the collection is loaded; otherwise, false . /// public bool IsLoaded { get { return _internalCollectionEntry.IsLoaded; } } /// /// Returns the query that would be used to load this collection from the database. /// The returned query can be modified using LINQ to perform filtering or operations in the database, such /// as counting the number of entities in the collection in the database without actually loading them. /// /// A query for the collection. public IQueryable Query() { return (IQueryable)_internalCollectionEntry.Query(); } #endregion #region Conversion to non-generic /// /// Returns a new instance of the non-generic class for /// the navigation property represented by this object. /// /// A non-generic version. [SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Justification = "Intentionally just implicit to reduce API clutter.")] public static implicit operator DbCollectionEntry(DbCollectionEntry entry) { return DbCollectionEntry.Create(entry._internalCollectionEntry); } #endregion #region Internal entry access /// /// Gets the underlying as an . /// /// The internal member entry. internal override InternalMemberEntry InternalMemberEntry { get { return _internalCollectionEntry; } } #endregion #region Back references /// /// The to which this navigation property belongs. /// /// An entry for the entity that owns this navigation property. public override DbEntityEntry EntityEntry { get { return new DbEntityEntry(_internalCollectionEntry.InternalEntityEntry); } } #endregion } }