Update Reference Sources to .NET Framework 4.6.1
[mono.git] / mcs / class / referencesource / System.Data.Entity / System / Data / Objects / ObjectStateManagerMetadata.cs
1 //---------------------------------------------------------------------
2 // <copyright file="ObjectStateManagerMetadata.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //
6 // @owner       [....]
7 // @backupOwner [....]
8 //---------------------------------------------------------------------
9 using System;
10 using System.Collections.Generic;
11 using System.Data.Common;
12 using System.Data.Metadata.Edm;
13 using System.Data.Mapping;
14 using System.Diagnostics;
15
16 namespace System.Data.Objects
17 {
18
19     internal struct EntitySetQualifiedType : IEqualityComparer<EntitySetQualifiedType>
20     {
21         internal static readonly IEqualityComparer<EntitySetQualifiedType> EqualityComparer = new EntitySetQualifiedType();        
22         
23         internal readonly Type ClrType;
24         internal readonly EntitySet EntitySet;
25
26         internal EntitySetQualifiedType(Type type, EntitySet set)
27         {
28             Debug.Assert(null != type, "null Type");
29             Debug.Assert(null != set, "null EntitySet");
30             Debug.Assert(null != set.EntityContainer, "null EntityContainer");
31             Debug.Assert(null != set.EntityContainer.Name, "null EntityContainer.Name");
32             ClrType = EntityUtil.GetEntityIdentityType(type);
33             EntitySet = set;
34         }
35
36         public bool Equals(EntitySetQualifiedType x, EntitySetQualifiedType y)
37         {
38             return (Object.ReferenceEquals(x.ClrType, y.ClrType) &&
39                     Object.ReferenceEquals(x.EntitySet, y.EntitySet));
40         }
41
42         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2303", Justification="ClrType is not expected to be an Embedded Interop Type.")]
43         public int GetHashCode(EntitySetQualifiedType obj)
44         {
45             return unchecked(obj.ClrType.GetHashCode() +
46                              obj.EntitySet.Name.GetHashCode() +
47                              obj.EntitySet.EntityContainer.Name.GetHashCode());
48         }
49     }
50
51     internal sealed class StateManagerMemberMetadata
52     {
53         private readonly EdmProperty _clrProperty; // may be null if shadowState
54         private readonly EdmProperty _edmProperty;
55         private readonly bool _isPartOfKey;
56         private readonly bool _isComplexType;
57
58         internal StateManagerMemberMetadata(ObjectPropertyMapping memberMap, EdmProperty memberMetadata, bool isPartOfKey)
59         {
60             // if memberMap is null, then this is a shadowstate
61             Debug.Assert(null != memberMap, "shadowstate not supported");
62             Debug.Assert(null != memberMetadata, "CSpace should never be null");
63             _clrProperty = memberMap.ClrProperty;
64             _edmProperty = memberMetadata;
65             _isPartOfKey = isPartOfKey;
66             _isComplexType = (Helper.IsEntityType(_edmProperty.TypeUsage.EdmType) ||
67                              Helper.IsComplexType(_edmProperty.TypeUsage.EdmType));
68         }
69
70         internal string CLayerName
71         {
72             get
73             {
74                 return _edmProperty.Name;
75             }
76         }
77
78         internal Type ClrType
79         {
80             get
81             {
82                 Debug.Assert(null != _clrProperty, "shadowstate not supported");
83                 return _clrProperty.TypeUsage.EdmType.ClrType;
84                 //return ((null != _clrProperty)
85                 //    ? _clrProperty.TypeUsage.EdmType.ClrType
86                 //    : (Helper.IsComplexType(_edmProperty)
87                 //        ? typeof(DbDataRecord)
88                 //        : ((PrimitiveType)_edmProperty.TypeUsage.EdmType).ClrEquivalentType));
89             }
90         }
91         internal bool IsComplex
92         {
93             get
94             {
95                 return _isComplexType;
96             }
97         }
98         internal EdmProperty CdmMetadata
99         {
100             get
101             {
102                 return _edmProperty;
103             }
104         }
105         internal EdmProperty ClrMetadata
106         {
107             get
108             {
109                 Debug.Assert(null != _clrProperty, "shadowstate not supported");
110                 return _clrProperty;
111             }
112         }
113         internal bool IsPartOfKey
114         {
115             get
116             {
117                 return _isPartOfKey;
118             }
119         }
120         public object GetValue(object userObject) // wrapp it in cacheentry
121         {
122             Debug.Assert(null != _clrProperty, "shadowstate not supported");
123             object dataObject = LightweightCodeGenerator.GetValue(_clrProperty, userObject);
124             return dataObject;
125         }
126         public void SetValue(object userObject, object value) // if record , unwrapp to object, use materializer in cacheentry
127         {
128             Debug.Assert(null != _clrProperty, "shadowstate not supported");
129             if (DBNull.Value == value)
130             {
131                 value = null;
132             }
133             if (IsComplex && value == null)
134             {
135                 throw EntityUtil.NullableComplexTypesNotSupported(CLayerName);
136             }
137             LightweightCodeGenerator.SetValue(_clrProperty, userObject, value);
138         }
139     }
140
141     internal sealed class StateManagerTypeMetadata
142     {
143         private readonly TypeUsage _typeUsage; // CSpace
144         private readonly ObjectTypeMapping _ocObjectMap;
145         private readonly StateManagerMemberMetadata[] _members;
146         private readonly Dictionary<string, int> _objectNameToOrdinal;
147         private readonly Dictionary<string, int> _cLayerNameToOrdinal;
148         private readonly DataRecordInfo _recordInfo;
149
150         internal StateManagerTypeMetadata(EdmType edmType, ObjectTypeMapping mapping)
151         {
152             Debug.Assert(null != edmType, "null EdmType");
153             Debug.Assert(Helper.IsEntityType(edmType) ||
154                          Helper.IsComplexType(edmType),
155                          "not Complex or EntityType");
156             Debug.Assert(Object.ReferenceEquals(mapping, null) ||
157                          Object.ReferenceEquals(mapping.EdmType, edmType),
158                          "different EdmType instance");
159
160             _typeUsage = TypeUsage.Create(edmType);
161             _recordInfo = new DataRecordInfo(_typeUsage);
162             _ocObjectMap = mapping;
163
164             ReadOnlyMetadataCollection<EdmProperty> members = TypeHelpers.GetProperties(edmType);
165             _members = new StateManagerMemberMetadata[members.Count];
166             _objectNameToOrdinal = new Dictionary<string, int>(members.Count);
167             _cLayerNameToOrdinal = new Dictionary<string, int>(members.Count);
168
169             ReadOnlyMetadataCollection<EdmMember> keyMembers = null;
170             if (Helper.IsEntityType(edmType))
171             {
172                 keyMembers = ((EntityType)edmType).KeyMembers;
173             }
174
175             for (int i = 0; i < _members.Length; ++i)
176             {
177                 EdmProperty member = members[i];
178
179                 ObjectPropertyMapping memberMap = null;
180                 if (null != mapping)
181                 {
182                     memberMap = mapping.GetPropertyMap(member.Name);
183                     if (null != memberMap)
184                     {
185                         _objectNameToOrdinal.Add(memberMap.ClrProperty.Name, i); // olayer name
186                     }
187                 }
188                 _cLayerNameToOrdinal.Add(member.Name, i); // clayer name
189
190                 // Determine whether this member is part of the identity of the entity.
191                 _members[i] = new StateManagerMemberMetadata(memberMap, member, ((null != keyMembers) && keyMembers.Contains(member)));
192             }
193         }
194
195         internal TypeUsage CdmMetadata
196         {
197             get
198             {
199                 return _typeUsage;
200             }
201         }
202         internal DataRecordInfo DataRecordInfo
203         {
204             get { return _recordInfo; }
205         }
206
207         internal int FieldCount
208         {
209             get
210             {
211                 return _members.Length;
212             }
213         }
214
215         internal Type GetFieldType(int ordinal)
216         {
217             return Member(ordinal).ClrType;
218         }
219
220         internal StateManagerMemberMetadata Member(int ordinal)
221         {
222             if (unchecked((uint)ordinal < (uint)_members.Length))
223             {
224                 return _members[ordinal];
225             }
226             throw EntityUtil.ArgumentOutOfRange("ordinal");
227         }
228
229         internal IEnumerable<StateManagerMemberMetadata> Members
230         {
231             get { return _members; }
232         }
233
234         internal string CLayerMemberName(int ordinal)
235         {
236             return Member(ordinal).CLayerName;
237         }
238         internal int GetOrdinalforOLayerMemberName(string name)
239         {
240             int ordinal;
241             if (String.IsNullOrEmpty(name) || !_objectNameToOrdinal.TryGetValue(name, out ordinal))
242             {
243                 ordinal = -1;
244             }
245             return ordinal;
246         }
247         internal int GetOrdinalforCLayerMemberName(string name)
248         {
249             int ordinal;
250             if (String.IsNullOrEmpty(name) || !_cLayerNameToOrdinal.TryGetValue(name, out ordinal))
251             {
252                 ordinal = -1;
253             }
254             return ordinal;
255         }
256         internal bool IsMemberPartofShadowState(int ordinal)
257         {
258             // 
259
260
261             Debug.Assert(Member(ordinal) != null,
262                 "The only case where Member(ordinal) can be null is if the property is in shadow state.  " +
263                 "When shadow state support is added, this assert should never fire.");
264             return (null == Member(ordinal).ClrMetadata);
265         }
266     }
267 }