//---------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner avickers
// @backupOwner jeffders
//---------------------------------------------------------------------
using System.Collections;
using System.Data.Objects.DataClasses;
using System.Runtime.CompilerServices;
using System.Data.Metadata.Edm;
namespace System.Data.Objects.Internal
{
///
/// Internally, entities are wrapped in some implementation of this
/// interface. This allows the RelationshipManager and other classes
/// to treat POCO entities and traditional entities in the same way
/// where ever possible.
///
internal interface IEntityWrapper
{
///
/// The Relationship Manager that is associated with the wrapped entity.
///
RelationshipManager RelationshipManager { get; }
///
/// Information about whether or not the entity instance actually owns and uses its RelationshipManager
/// This is used to determine how to do relationship fixup in some cases
///
bool OwnsRelationshipManager { get; }
///
/// The actual entity that is wrapped by this wrapper object.
///
object Entity { get; }
///
/// If this IEntityWrapper is tracked, accesses the ObjectStateEntry that is used in the state manager
///
EntityEntry ObjectStateEntry { get; set; }
///
/// Ensures that the collection with the given name is not null by setting a new empty
/// collection onto the property if necessary.
///
/// The name of the collection to operate on
void EnsureCollectionNotNull(RelatedEnd relatedEnd);
///
/// The key associated with this entity, which may be null if no key is known.
///
EntityKey EntityKey { get; set; }
///
/// Retrieves the EntityKey from the entity if it implements IEntityWithKey
///
/// The EntityKey on the entity
EntityKey GetEntityKeyFromEntity();
///
/// The context with which the wrapped entity is associated, or null if the entity
/// is detached.
///
ObjectContext Context { get; set; }
///
/// The merge option assoicated with the wrapped entity.
///
MergeOption MergeOption { get; }
///
/// Attaches the wrapped entity to the given context.
///
/// the context with which to associate this entity
/// the entity set to which the entity belongs
/// the merge option to use
void AttachContext(ObjectContext context, EntitySet entitySet, MergeOption mergeOption);
///
/// Resets the context with which the wrapped entity is associated.
///
/// the context with which to associate this entity
/// the entity set to which the entity belongs
/// the merge option to use
void ResetContext(ObjectContext context, EntitySet entitySet, MergeOption mergeOption);
///
/// Detaches the wrapped entity from its associated context.
///
void DetachContext();
///
/// Sets the entity's ObjectStateEntry as the entity's change tracker if possible.
/// The ObjectStateEntry may be null when a change tracker is being removed from an
/// entity.
///
/// the object to use as a change tracker
void SetChangeTracker(IEntityChangeTracker changeTracker);
///
/// Takes a snapshot of the entity state unless the entity has an associated
/// change tracker or the given entry is null, in which case no action is taken.
///
/// the entity's associated state entry
void TakeSnapshot(EntityEntry entry);
///
/// Takes a snapshot of the relationships of the entity stored in the entry
///
///
void TakeSnapshotOfRelationships(EntityEntry entry);
///
/// The Type object that should be used to identify this entity in o-space.
/// This is normally just the type of the entity object, but if the object
/// is a proxy that we have generated, then the type of the base class is returned instead.
/// This ensures that both proxy entities and normal entities are treated as the
/// same kind of entity in the metadata and places where the metadata is used.
///
Type IdentityType { get; }
///
/// Populates a value into a collection of values stored in a property of the entity.
/// If the collection to be populated is actually managed by and returned from
/// the RelationshipManager when needed, then this method is a no-op. This is
/// typically the case for non-POCO entities.
///
void CollectionAdd(RelatedEnd relatedEnd, object value);
///
/// Removes a value from a collection of values stored in a property of the entity.
/// If the collection to be updated is actually managed by and returned from
/// the RelationshipManager when needed, then this method is a no-op. This is
/// typically the case for non-POCO entities.
///
bool CollectionRemove(RelatedEnd relatedEnd, object value);
///
/// Returns value of the entity's property described by the navigation property.
///
/// navigation property to retrieve
///
object GetNavigationPropertyValue(RelatedEnd relatedEnd);
///
/// Populates a single value into a field or property of the entity.
/// If the element to be populated is actually managed by and returned from
/// the RelationshipManager when needed, then this method is a no-op. This is
/// typically the case for non-POCO entities.
///
void SetNavigationPropertyValue(RelatedEnd relatedEnd, object value);
///
/// Removes a single value from a field or property of the entity.
/// If the field or property contains reference to a different object,
/// this method is a no-op.
/// If the element to be populated is actually managed by and returned from
/// the RelationshipManager when needed, then this method is a no-op. This is
/// typically the case for non-POCO entities.
///
/// The value to remove
void RemoveNavigationPropertyValue(RelatedEnd relatedEnd, object value);
///
/// Sets the given value onto the entity with the registered change either handled by the
/// entity itself or by using the given EntityEntry as the change tracker.
///
/// The state entry of the entity to for which a value should be set
/// State member information indicating the member to set
/// The ordinal of the member to set
/// The object onto which the value should be set; may be the entity, or a contained complex value
/// The value to set
void SetCurrentValue(EntityEntry entry, StateManagerMemberMetadata member, int ordinal, object target, object value);
///
/// Set to true while the process of initalizing RelatedEnd objects for an IPOCO proxy is in process.
/// This flag prevents the context from being set onto the related ends, which in turn means that
/// the related ends don't need to have keys, which in turn means they don't need to be part of an EntitySet.
///
bool InitializingProxyRelatedEnds { get; set; }
///
/// Updates the current value records using Shaper.UpdateRecord but with additional change tracking logic
/// added as required by POCO and proxy entities. For the simple case of no proxy and an entity with
/// a change tracker, this translates into a simple call to ShaperUpdateRecord.
///
/// The value
/// The existing ObjectStateEntry
void UpdateCurrentValueRecord(object value, EntityEntry entry);
///
/// True if the underlying entity is not capable of tracking changes to relationships such that
/// DetectChanges is required to do this.
///
bool RequiresRelationshipChangeTracking { get; }
}
}