1 //---------------------------------------------------------------------
2 // <copyright file="LightweightEntityWrapper.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
9 using System.Collections;
10 using System.Data.Objects.DataClasses;
11 using System.Diagnostics;
12 using System.Reflection;
13 using System.Data.Metadata.Edm;
15 namespace System.Data.Objects.Internal
18 /// Implementation of IEntityWrapper for any entity that implements IEntityWithChangeTracker, IEntityWithRelationships,
19 /// and IEntityWithKey and is not a proxy. This is a lightweight wrapper that delegates functionality to those iterfaces.
20 /// This improves the speed and memory utilization for the standard code-gen cases in materialization.
22 /// <typeparam name="TEntity">The type of entity wrapped</typeparam>
23 internal sealed class LightweightEntityWrapper<TEntity> : BaseEntityWrapper<TEntity>
24 where TEntity : IEntityWithRelationships, IEntityWithKey, IEntityWithChangeTracker
26 private readonly TEntity _entity;
29 /// Constructs a wrapper for the given entity.
30 /// Note: use EntityWrapperFactory instead of calling this constructor directly.
32 /// <param name="entity">The entity to wrap</param>
33 internal LightweightEntityWrapper(TEntity entity)
34 : base(entity, entity.RelationshipManager)
36 Debug.Assert(entity is IEntityWithChangeTracker, "LightweightEntityWrapper only works with entities that implement IEntityWithChangeTracker");
37 Debug.Assert(entity is IEntityWithRelationships, "LightweightEntityWrapper only works with entities that implement IEntityWithRelationships");
38 Debug.Assert(entity is IEntityWithKey, "LightweightEntityWrapper only works with entities that implement IEntityWithKey");
39 Debug.Assert(!EntityProxyFactory.IsProxyType(entity.GetType()), "LightweightEntityWrapper only works with entities that are not proxies");
44 /// Constructs a wrapper as part of the materialization process. This constructor is only used
45 /// during materialization where it is known that the entity being wrapped is newly constructed.
46 /// This means that some checks are not performed that might be needed when thw wrapper is
47 /// created at other times, and information such as the identity type is passed in because
48 /// it is readily available in the materializer.
50 /// <param name="entity">The entity to wrap</param>
51 /// <param name="key">The key for the entity</param>
52 /// <param name="entitySet">The entity set, or null if none is known</param>
53 /// <param name="context">The context to which the entity should be attached</param>
54 /// <param name="mergeOption">NoTracking for non-tracked entities, AppendOnly otherwise</param>
55 /// <param name="identityType">The type of the entity ignoring any possible proxy type</param>
56 internal LightweightEntityWrapper(TEntity entity, EntityKey key, EntitySet entitySet, ObjectContext context, MergeOption mergeOption, Type identityType)
57 : base(entity, entity.RelationshipManager, entitySet, context, mergeOption, identityType)
59 Debug.Assert(entity is IEntityWithChangeTracker, "LightweightEntityWrapper only works with entities that implement IEntityWithChangeTracker");
60 Debug.Assert(entity is IEntityWithRelationships, "LightweightEntityWrapper only works with entities that implement IEntityWithRelationships");
61 Debug.Assert(entity is IEntityWithKey, "LightweightEntityWrapper only works with entities that implement IEntityWithKey");
62 Debug.Assert(!EntityProxyFactory.IsProxyType(entity.GetType()), "LightweightEntityWrapper only works with entities that are not proxies");
64 _entity.EntityKey = key;
67 // See IEntityWrapper documentation
68 public override void SetChangeTracker(IEntityChangeTracker changeTracker)
70 _entity.SetChangeTracker(changeTracker);
73 // See IEntityWrapper documentation
74 public override void TakeSnapshot(EntityEntry entry)
78 // See IEntityWrapper documentation
79 public override void TakeSnapshotOfRelationships(EntityEntry entry)
83 // See IEntityWrapper documentation
84 public override EntityKey EntityKey
88 return _entity.EntityKey;
92 _entity.EntityKey = value;
96 public override bool OwnsRelationshipManager
101 // See IEntityWrapper documentation
102 public override EntityKey GetEntityKeyFromEntity()
104 return _entity.EntityKey;
107 // See IEntityWrapper documentation
108 public override void CollectionAdd(RelatedEnd relatedEnd, object value)
112 // See IEntityWrapper documentation
113 public override bool CollectionRemove(RelatedEnd relatedEnd, object value)
118 // See IEntityWrapper documentation
119 public override void SetNavigationPropertyValue(RelatedEnd relatedEnd, object value)
123 // See IEntityWrapper documentation
124 public override void RemoveNavigationPropertyValue(RelatedEnd relatedEnd, object value)
128 // See IEntityWrapper documentation
129 public override void EnsureCollectionNotNull(RelatedEnd relatedEnd)
133 // See IEntityWrapper documentation
134 public override object GetNavigationPropertyValue(RelatedEnd relatedEnd)
139 // See IEntityWrapper documentation
140 public override object Entity
142 get { return _entity; }
145 // See IEntityWrapper<TEntity> documentation
146 public override TEntity TypedEntity
148 get { return _entity; }
151 // See IEntityWrapper documentation
152 public override void SetCurrentValue(EntityEntry entry, StateManagerMemberMetadata member, int ordinal, object target, object value)
154 member.SetValue(target, value);
157 // See IEntityWrapper documentation
158 public override void UpdateCurrentValueRecord(object value, EntityEntry entry)
160 // No extra work to do because we know that the entity is not a proxy and has a change tracker
161 entry.UpdateRecordWithoutSetModified(value, entry.CurrentValues);
164 // See IEntityWrapper documentation
165 public override bool RequiresRelationshipChangeTracking
167 get { return false; }