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