1 //---------------------------------------------------------------------
2 // <copyright file="ObjectStateManagerMetadata.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
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
;
16 namespace System
.Data
.Objects
19 internal struct EntitySetQualifiedType
: IEqualityComparer
<EntitySetQualifiedType
>
21 internal static readonly IEqualityComparer
<EntitySetQualifiedType
> EqualityComparer
= new EntitySetQualifiedType();
23 internal readonly Type ClrType
;
24 internal readonly EntitySet EntitySet
;
26 internal EntitySetQualifiedType(Type type
, EntitySet
set)
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
);
36 public bool Equals(EntitySetQualifiedType x
, EntitySetQualifiedType y
)
38 return (Object
.ReferenceEquals(x
.ClrType
, y
.ClrType
) &&
39 Object
.ReferenceEquals(x
.EntitySet
, y
.EntitySet
));
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
)
45 return unchecked(obj
.ClrType
.GetHashCode() +
46 obj
.EntitySet
.Name
.GetHashCode() +
47 obj
.EntitySet
.EntityContainer
.Name
.GetHashCode());
51 internal sealed class StateManagerMemberMetadata
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
;
58 internal StateManagerMemberMetadata(ObjectPropertyMapping memberMap
, EdmProperty memberMetadata
, bool isPartOfKey
)
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
));
70 internal string CLayerName
74 return _edmProperty
.Name
;
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));
91 internal bool IsComplex
95 return _isComplexType
;
98 internal EdmProperty CdmMetadata
105 internal EdmProperty ClrMetadata
109 Debug
.Assert(null != _clrProperty
, "shadowstate not supported");
113 internal bool IsPartOfKey
120 public object GetValue(object userObject
) // wrapp it in cacheentry
122 Debug
.Assert(null != _clrProperty
, "shadowstate not supported");
123 object dataObject
= LightweightCodeGenerator
.GetValue(_clrProperty
, userObject
);
126 public void SetValue(object userObject
, object value) // if record , unwrapp to object, use materializer in cacheentry
128 Debug
.Assert(null != _clrProperty
, "shadowstate not supported");
129 if (DBNull
.Value
== value)
133 if (IsComplex
&& value == null)
135 throw EntityUtil
.NullableComplexTypesNotSupported(CLayerName
);
137 LightweightCodeGenerator
.SetValue(_clrProperty
, userObject
, value);
141 internal sealed class StateManagerTypeMetadata
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
;
150 internal StateManagerTypeMetadata(EdmType edmType
, ObjectTypeMapping mapping
)
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");
160 _typeUsage
= TypeUsage
.Create(edmType
);
161 _recordInfo
= new DataRecordInfo(_typeUsage
);
162 _ocObjectMap
= mapping
;
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
);
169 ReadOnlyMetadataCollection
<EdmMember
> keyMembers
= null;
170 if (Helper
.IsEntityType(edmType
))
172 keyMembers
= ((EntityType
)edmType
).KeyMembers
;
175 for (int i
= 0; i
< _members
.Length
; ++i
)
177 EdmProperty member
= members
[i
];
179 ObjectPropertyMapping memberMap
= null;
182 memberMap
= mapping
.GetPropertyMap(member
.Name
);
183 if (null != memberMap
)
185 _objectNameToOrdinal
.Add(memberMap
.ClrProperty
.Name
, i
); // olayer name
188 _cLayerNameToOrdinal
.Add(member
.Name
, i
); // clayer name
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
)));
195 internal TypeUsage CdmMetadata
202 internal DataRecordInfo DataRecordInfo
204 get { return _recordInfo; }
207 internal int FieldCount
211 return _members
.Length
;
215 internal Type
GetFieldType(int ordinal
)
217 return Member(ordinal
).ClrType
;
220 internal StateManagerMemberMetadata
Member(int ordinal
)
222 if (unchecked((uint)ordinal
< (uint)_members
.Length
))
224 return _members
[ordinal
];
226 throw EntityUtil
.ArgumentOutOfRange("ordinal");
229 internal IEnumerable
<StateManagerMemberMetadata
> Members
231 get { return _members; }
234 internal string CLayerMemberName(int ordinal
)
236 return Member(ordinal
).CLayerName
;
238 internal int GetOrdinalforOLayerMemberName(string name
)
241 if (String
.IsNullOrEmpty(name
) || !_objectNameToOrdinal
.TryGetValue(name
, out ordinal
))
247 internal int GetOrdinalforCLayerMemberName(string name
)
250 if (String
.IsNullOrEmpty(name
) || !_cLayerNameToOrdinal
.TryGetValue(name
, out ordinal
))
256 internal bool IsMemberPartofShadowState(int ordinal
)
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
);