874b4c0d0f3af29cac59beda30ba3f2cb8ebac63
[mono.git] / mcs / class / referencesource / System.Data.Entity / System / Data / Objects / Internal / LightweightEntityWrapper.cs
1 //---------------------------------------------------------------------
2 // <copyright file="LightweightEntityWrapper.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //
6 // @owner       Microsoft
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;
14
15 namespace System.Data.Objects.Internal
16 {
17     /// <summary>
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.
21     /// </summary>
22     /// <typeparam name="TEntity">The type of entity wrapped</typeparam>
23     internal sealed class LightweightEntityWrapper<TEntity> : BaseEntityWrapper<TEntity>
24              where TEntity : IEntityWithRelationships, IEntityWithKey, IEntityWithChangeTracker
25     {
26         private readonly TEntity _entity;
27
28         /// <summary>
29         /// Constructs a wrapper for the given entity.
30         /// Note: use EntityWrapperFactory instead of calling this constructor directly.
31         /// </summary>
32         /// <param name="entity">The entity to wrap</param>
33         internal LightweightEntityWrapper(TEntity entity)
34         : base(entity, entity.RelationshipManager)
35         {
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");
40             _entity = entity;
41         }
42
43         /// <summary>
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.
49         /// </summary>
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)
58         {
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");
63             _entity = entity;
64             _entity.EntityKey = key;
65         }
66
67         // See IEntityWrapper documentation
68         public override void SetChangeTracker(IEntityChangeTracker changeTracker)
69         {
70             _entity.SetChangeTracker(changeTracker);
71         }
72
73         // See IEntityWrapper documentation
74         public override void TakeSnapshot(EntityEntry entry)
75         {
76         }
77
78         // See IEntityWrapper documentation
79         public override void TakeSnapshotOfRelationships(EntityEntry entry)
80         {
81         }
82
83         // See IEntityWrapper documentation
84         public override EntityKey EntityKey
85         {
86             get
87             {
88                 return _entity.EntityKey;
89             }
90             set
91             {
92                 _entity.EntityKey = value;
93             }
94         }
95
96         public override bool OwnsRelationshipManager
97         {
98             get { return true; }
99         }
100
101         // See IEntityWrapper documentation
102         public override EntityKey GetEntityKeyFromEntity()
103         {
104             return _entity.EntityKey;
105         }
106
107         // See IEntityWrapper documentation
108         public override void CollectionAdd(RelatedEnd relatedEnd, object value)
109         {
110         }
111
112         // See IEntityWrapper documentation
113         public override bool CollectionRemove(RelatedEnd relatedEnd, object value)
114         {
115             return false;
116         }
117         
118         // See IEntityWrapper documentation
119         public override void SetNavigationPropertyValue(RelatedEnd relatedEnd, object value)
120         {
121         }
122
123         // See IEntityWrapper documentation
124         public override void RemoveNavigationPropertyValue(RelatedEnd relatedEnd, object value)
125         {
126         }
127
128         // See IEntityWrapper documentation
129         public override void EnsureCollectionNotNull(RelatedEnd relatedEnd)
130         {
131         }
132
133         // See IEntityWrapper documentation
134         public override object GetNavigationPropertyValue(RelatedEnd relatedEnd)
135         {
136             return null;
137         }
138
139         // See IEntityWrapper documentation
140         public override object Entity
141         {
142             get { return _entity; }
143         }
144
145         // See IEntityWrapper<TEntity> documentation
146         public override TEntity TypedEntity
147         {
148             get { return _entity; }
149         }
150
151         // See IEntityWrapper documentation
152         public override void SetCurrentValue(EntityEntry entry, StateManagerMemberMetadata member, int ordinal, object target, object value)
153         {
154             member.SetValue(target, value);
155         }
156
157         // See IEntityWrapper documentation
158         public override void UpdateCurrentValueRecord(object value, EntityEntry entry)
159         {
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);
162         }
163
164         // See IEntityWrapper documentation
165         public override bool RequiresRelationshipChangeTracking
166         {
167             get { return false; }
168         }
169     }
170 }