1 //--------------------------------------------------------------------- 2 // <copyright file="IEntityWrapper.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 5 // 6 // @owner avickers 7 // @backupOwner jeffders 8 //--------------------------------------------------------------------- 9 using System.Collections; 10 using System.Data.Objects.DataClasses; 11 using System.Runtime.CompilerServices; 12 using System.Data.Metadata.Edm; 13 14 namespace System.Data.Objects.Internal 15 { 16 /// <summary> 17 /// Internally, entities are wrapped in some implementation of this 18 /// interface. This allows the RelationshipManager and other classes 19 /// to treat POCO entities and traditional entities in the same way 20 /// where ever possible. 21 /// </summary> 22 internal interface IEntityWrapper 23 { 24 /// <summary> 25 /// The Relationship Manager that is associated with the wrapped entity. 26 /// </summary> 27 RelationshipManager RelationshipManager { get; } 28 29 /// <summary> 30 /// Information about whether or not the entity instance actually owns and uses its RelationshipManager 31 /// This is used to determine how to do relationship fixup in some cases 32 /// </summary> 33 bool OwnsRelationshipManager { get; } 34 35 /// <summary> 36 /// The actual entity that is wrapped by this wrapper object. 37 /// </summary> 38 object Entity { get; } 39 40 /// <summary> 41 /// If this IEntityWrapper is tracked, accesses the ObjectStateEntry that is used in the state manager 42 /// </summary> 43 EntityEntry ObjectStateEntry { get; set; } 44 45 /// <summary> 46 /// Ensures that the collection with the given name is not null by setting a new empty 47 /// collection onto the property if necessary. 48 /// </summary> 49 /// <param name="collectionName">The name of the collection to operate on</param> EnsureCollectionNotNull(RelatedEnd relatedEnd)50 void EnsureCollectionNotNull(RelatedEnd relatedEnd); 51 52 /// <summary> 53 /// The key associated with this entity, which may be null if no key is known. 54 /// </summary> 55 EntityKey EntityKey { get; set; } 56 57 /// <summary> 58 /// Retrieves the EntityKey from the entity if it implements IEntityWithKey 59 /// </summary> 60 /// <returns>The EntityKey on the entity</returns> GetEntityKeyFromEntity()61 EntityKey GetEntityKeyFromEntity(); 62 63 /// <summary> 64 /// The context with which the wrapped entity is associated, or null if the entity 65 /// is detached. 66 /// </summary> 67 ObjectContext Context { get; set; } 68 69 /// <summary> 70 /// The merge option assoicated with the wrapped entity. 71 /// </summary> 72 MergeOption MergeOption { get; } 73 74 /// <summary> 75 /// Attaches the wrapped entity to the given context. 76 /// </summary> 77 /// <param name="context">the context with which to associate this entity</param> 78 /// <param name="entitySet">the entity set to which the entity belongs</param> 79 /// <param name="mergeOption">the merge option to use</param> AttachContext(ObjectContext context, EntitySet entitySet, MergeOption mergeOption)80 void AttachContext(ObjectContext context, EntitySet entitySet, MergeOption mergeOption); 81 82 /// <summary> 83 /// Resets the context with which the wrapped entity is associated. 84 /// </summary> 85 /// <param name="context">the context with which to associate this entity</param> 86 /// <param name="entitySet">the entity set to which the entity belongs</param> 87 /// <param name="mergeOption">the merge option to use</param> ResetContext(ObjectContext context, EntitySet entitySet, MergeOption mergeOption)88 void ResetContext(ObjectContext context, EntitySet entitySet, MergeOption mergeOption); 89 90 /// <summary> 91 /// Detaches the wrapped entity from its associated context. 92 /// </summary> DetachContext()93 void DetachContext(); 94 95 /// <summary> 96 /// Sets the entity's ObjectStateEntry as the entity's change tracker if possible. 97 /// The ObjectStateEntry may be null when a change tracker is being removed from an 98 /// entity. 99 /// </summary> 100 /// <param name="changeTracker">the object to use as a change tracker</param> SetChangeTracker(IEntityChangeTracker changeTracker)101 void SetChangeTracker(IEntityChangeTracker changeTracker); 102 103 /// <summary> 104 /// Takes a snapshot of the entity state unless the entity has an associated 105 /// change tracker or the given entry is null, in which case no action is taken. 106 /// </summary> 107 /// <param name="entry">the entity's associated state entry</param> TakeSnapshot(EntityEntry entry)108 void TakeSnapshot(EntityEntry entry); 109 110 /// <summary> 111 /// Takes a snapshot of the relationships of the entity stored in the entry 112 /// </summary> 113 /// <param name="entry"></param> TakeSnapshotOfRelationships(EntityEntry entry)114 void TakeSnapshotOfRelationships(EntityEntry entry); 115 116 /// <summary> 117 /// The Type object that should be used to identify this entity in o-space. 118 /// This is normally just the type of the entity object, but if the object 119 /// is a proxy that we have generated, then the type of the base class is returned instead. 120 /// This ensures that both proxy entities and normal entities are treated as the 121 /// same kind of entity in the metadata and places where the metadata is used. 122 /// </summary> 123 Type IdentityType { get; } 124 125 /// <summary> 126 /// Populates a value into a collection of values stored in a property of the entity. 127 /// If the collection to be populated is actually managed by and returned from 128 /// the RelationshipManager when needed, then this method is a no-op. This is 129 /// typically the case for non-POCO entities. 130 /// </summary> CollectionAdd(RelatedEnd relatedEnd, object value)131 void CollectionAdd(RelatedEnd relatedEnd, object value); 132 133 /// <summary> 134 /// Removes a value from a collection of values stored in a property of the entity. 135 /// If the collection to be updated is actually managed by and returned from 136 /// the RelationshipManager when needed, then this method is a no-op. This is 137 /// typically the case for non-POCO entities. 138 /// </summary> CollectionRemove(RelatedEnd relatedEnd, object value)139 bool CollectionRemove(RelatedEnd relatedEnd, object value); 140 141 /// <summary> 142 /// Returns value of the entity's property described by the navigation property. 143 /// </summary> 144 /// <param name="relatedEnd">navigation property to retrieve</param> 145 /// <returns></returns> GetNavigationPropertyValue(RelatedEnd relatedEnd)146 object GetNavigationPropertyValue(RelatedEnd relatedEnd); 147 148 /// <summary> 149 /// Populates a single value into a field or property of the entity. 150 /// If the element to be populated is actually managed by and returned from 151 /// the RelationshipManager when needed, then this method is a no-op. This is 152 /// typically the case for non-POCO entities. 153 /// </summary> SetNavigationPropertyValue(RelatedEnd relatedEnd, object value)154 void SetNavigationPropertyValue(RelatedEnd relatedEnd, object value); 155 156 /// <summary> 157 /// Removes a single value from a field or property of the entity. 158 /// If the field or property contains reference to a different object, 159 /// this method is a no-op. 160 /// If the element to be populated is actually managed by and returned from 161 /// the RelationshipManager when needed, then this method is a no-op. This is 162 /// typically the case for non-POCO entities. 163 /// </summary> 164 /// <param name="value">The value to remove</param> RemoveNavigationPropertyValue(RelatedEnd relatedEnd, object value)165 void RemoveNavigationPropertyValue(RelatedEnd relatedEnd, object value); 166 167 /// <summary> 168 /// Sets the given value onto the entity with the registered change either handled by the 169 /// entity itself or by using the given EntityEntry as the change tracker. 170 /// </summary> 171 /// <param name="entry">The state entry of the entity to for which a value should be set</param> 172 /// <param name="member">State member information indicating the member to set</param> 173 /// <param name="ordinal">The ordinal of the member to set</param> 174 /// <param name="target">The object onto which the value should be set; may be the entity, or a contained complex value</param> 175 /// <param name="value">The value to set</param> SetCurrentValue(EntityEntry entry, StateManagerMemberMetadata member, int ordinal, object target, object value)176 void SetCurrentValue(EntityEntry entry, StateManagerMemberMetadata member, int ordinal, object target, object value); 177 178 /// <summary> 179 /// Set to true while the process of initalizing RelatedEnd objects for an IPOCO proxy is in process. 180 /// This flag prevents the context from being set onto the related ends, which in turn means that 181 /// the related ends don't need to have keys, which in turn means they don't need to be part of an EntitySet. 182 /// </summary> 183 bool InitializingProxyRelatedEnds { get; set; } 184 185 /// <summary> 186 /// Updates the current value records using Shaper.UpdateRecord but with additional change tracking logic 187 /// added as required by POCO and proxy entities. For the simple case of no proxy and an entity with 188 /// a change tracker, this translates into a simple call to ShaperUpdateRecord. 189 /// </summary> 190 /// <param name="value">The value</param> 191 /// <param name="entry">The existing ObjectStateEntry</param> UpdateCurrentValueRecord(object value, EntityEntry entry)192 void UpdateCurrentValueRecord(object value, EntityEntry entry); 193 194 /// <summary> 195 /// True if the underlying entity is not capable of tracking changes to relationships such that 196 /// DetectChanges is required to do this. 197 /// </summary> 198 bool RequiresRelationshipChangeTracking { get; } 199 } 200 } 201