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