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