/// <summary>Gets the type name to be used in the URI for the given <paramref name="type"/>.</summary> /// <param name="type">Type to get name for.</param> /// <param name="context">Data context used to generate type names for types.</param> /// <returns>The name for the <paramref name="type"/>, suitable for including in a URI.</returns> internal static string GetTypeNameForUri(Type type, DataServiceContext context) { Debug.Assert(type != null, "type != null"); Debug.Assert(context != null, "context != null"); type = Nullable.GetUnderlyingType(type) ?? type; PrimitiveType pt; if (PrimitiveType.TryGetPrimitiveType(type, out pt)) { if (pt.HasReverseMapping) { return(pt.EdmTypeName); } else { // unsupported primitive type throw new NotSupportedException(Strings.ALinq_CantCastToUnsupportedPrimitive(type.Name)); } } else { return(context.ResolveNameFromType(type) ?? type.FullName); } }
internal ClientTypeAnnotation ResolveEdmTypeName(Type expectedType, string edmTypeName) { ClientTypeAnnotation clientTypeAnnotation; PrimitiveType type; string collectionItemWireTypeName = WebUtil.GetCollectionItemWireTypeName(edmTypeName); string str2 = collectionItemWireTypeName ?? edmTypeName; ClientEdmModel model = ClientEdmModel.GetModel(this.ResponseInfo.MaxProtocolVersion); if (PrimitiveType.TryGetPrimitiveType(str2, out type)) { clientTypeAnnotation = model.GetClientTypeAnnotation(type.ClrType); } else if (!this.edmTypeNameMap.TryGetValue(str2, out clientTypeAnnotation)) { clientTypeAnnotation = model.GetClientTypeAnnotation(str2); } if (collectionItemWireTypeName == null) { return(clientTypeAnnotation); } Type elementType = clientTypeAnnotation.ElementType; if (type != null) { elementType = ClientTypeUtil.GetImplementationType(expectedType, typeof(ICollection <>)).GetGenericArguments()[0]; } Type backingTypeForCollectionProperty = WebUtil.GetBackingTypeForCollectionProperty(expectedType, elementType); return(model.GetClientTypeAnnotation(backingTypeForCollectionProperty)); }
/// <summary> /// convert from string to the appropriate type /// </summary> /// <param name="propertyValue">incoming string value</param> /// <param name="propertyType">type to convert to</param> /// <returns>converted value</returns> internal static object ChangeType(string propertyValue, Type propertyType) { Debug.Assert(null != propertyValue, "should never be passed null"); PrimitiveType primitiveType; if (PrimitiveType.TryGetPrimitiveType(propertyType, out primitiveType) && primitiveType.TypeConverter != null) { try { // functionality provided by type converter return(primitiveType.TypeConverter.Parse(propertyValue)); } catch (FormatException ex) { propertyValue = (0 == propertyValue.Length ? "String.Empty" : "String"); throw Error.InvalidOperation(Strings.Deserialize_Current(propertyType.ToString(), propertyValue), ex); } catch (OverflowException ex) { propertyValue = (0 == propertyValue.Length ? "String.Empty" : "String"); throw Error.InvalidOperation(Strings.Deserialize_Current(propertyType.ToString(), propertyValue), ex); } } else { Debug.Assert(false, "new StorageType without update to knownTypes"); return(propertyValue); } }
/// <summary>type edm type string for content</summary> /// <param name="propertyType">type to analyze</param> /// <returns>edm type string for payload, null for unknown</returns> internal static string GetEdmType(Type propertyType) { PrimitiveType primitiveType; if (PrimitiveType.TryGetPrimitiveType(propertyType, out primitiveType)) { if (primitiveType.EdmTypeName != null) { return(primitiveType.EdmTypeName); } else { // case StorageType.UInt16: // case StorageType.UInt32: // case StorageType.UInt64: // don't support reverse mappings for these types in this version // allows us to add real server support in the future without a // "breaking change" in the future client throw new NotSupportedException(Strings.ALinq_CantCastToUnsupportedPrimitive(propertyType.Name)); } } else { Debug.Assert(false, "knowntype without reverse mapping"); return(null); } }
internal static string ToString(object propertyValue) { PrimitiveType type; if (PrimitiveType.TryGetPrimitiveType(propertyValue.GetType(), out type) && (type.TypeConverter != null)) { return(type.TypeConverter.ToString(propertyValue)); } return(propertyValue.ToString()); }
/// <summary> /// Returns the primitive property value. /// </summary> /// <param name="propertyValue">Value of the property.</param> /// <param name="propertyType">Type of the property.</param> /// <returns>Returns the value of the primitive property.</returns> private static object ConvertPrimitiveValueToRecognizedODataType(object propertyValue, Type propertyType) { Debug.Assert(PrimitiveType.IsKnownNullableType(propertyType), "GetPrimitiveValue must be called only for primitive types"); Debug.Assert(propertyValue == null || PrimitiveType.IsKnownType(propertyValue.GetType()), "GetPrimitiveValue method must be called for primitive values only"); if (propertyValue == null) { return(null); } PrimitiveType primitiveType; PrimitiveType.TryGetPrimitiveType(propertyType, out primitiveType); Debug.Assert(primitiveType != null, "must be a known primitive type"); // Do the conversion for types that are not supported by ODataLib e.g. char[], char, etc if (propertyType == typeof(Char) || propertyType == typeof(Char[]) || propertyType == typeof(Type) || propertyType == typeof(Uri) || propertyType == typeof(Xml.Linq.XDocument) || propertyType == typeof(Xml.Linq.XElement)) { return(primitiveType.TypeConverter.ToString(propertyValue)); } #if !ASTORIA_LIGHT && !PORTABLELIB else if (propertyType.FullName == "System.Data.Linq.Binary") { // For System.Data.Linq.Binary, it is a delay loaded type. Hence checking it based on name. // PrimitiveType.IsKnownType checks for binary type based on name and assembly. Hence just // checking name here is sufficient, since any other type with the same name, but in different // assembly will return false for PrimitiveType.IsKnownNullableType. // Since ODataLib does not understand binary type, we need to convert the value to byte[]. return(((BinaryTypeConverter)primitiveType.TypeConverter).ToArray(propertyValue)); } #endif else if (primitiveType.EdmTypeName == null) { // case StorageType.DateTimeOffset: // case StorageType.TimeSpan: // case StorageType.UInt16: // case StorageType.UInt32: // case StorageType.UInt64: // don't support reverse mappings for these types in this version // allows us to add real server support in the future without a // "breaking change" in the future client throw new NotSupportedException(Strings.ALinq_CantCastToUnsupportedPrimitive(propertyType.Name)); } return(propertyValue); }
/// <summary> /// Resolves the client type that should be used for materialization. /// </summary> /// <param name="expectedType">Expected client clr type based on the API called.</param> /// <param name="readerTypeName"> /// The name surfaced by the ODataLib reader. /// If we have a server model, this will be a server type name that needs to be resolved. /// If not, then this will already be a client type name.</param> /// <returns>The resolved annotation for the client type to materialize into.</returns> internal ClientTypeAnnotation ResolveTypeForMaterialization(Type expectedType, string readerTypeName) { // If its a collection, get the collection item name string collectionItemTypeName = WebUtil.GetCollectionItemWireTypeName(readerTypeName); if (collectionItemTypeName == null) { // Resolve the primitive type first PrimitiveType primitiveType; if (PrimitiveType.TryGetPrimitiveType(readerTypeName, out primitiveType)) { return(this.clientEdmModel.GetClientTypeAnnotation(primitiveType.ClrType)); } ClientTypeAnnotation resultType; if (this.edmTypeNameMap.TryGetValue(readerTypeName, out resultType)) { return(resultType); } if (this.serviceModel != null) { var resolvedType = this.ResolveTypeFromName(readerTypeName, expectedType); return(this.clientEdmModel.GetClientTypeAnnotation(resolvedType)); } // If there was no type name specified in the payload, then the type resolver won't be invoked // and hence that edm type name might not be in the resolver cache. Hence look that up in the // ClientEdmModel cache. This lookup is more expensive and is unique across the app domain for the // given version. return(this.clientEdmModel.GetClientTypeAnnotation(readerTypeName)); } Type collectionImplementationType = ClientTypeUtil.GetImplementationType(expectedType, typeof(ICollection <>)); Type collectionElementType = collectionImplementationType.GetGenericArguments()[0]; // In case of collection, the expectedType might be collection of nullable types (for e.g. ICollection<int?>). // There is no way to know the nullability from the wireTypeName (For e.g. Collection(Edm.Int32)). // Hence in case of collections of primitives, we need to look at the element type of the expected type // and use that to create the instance otherwise we will not be able to assign the created ICollection<> // instance to the property on the user's entity (ICollection<int> cannot be assigned to ICollection<int?>). // There is also no need to invoke the resolver for primitives, so we just use the element type. if (!PrimitiveType.IsKnownType(collectionElementType)) { collectionElementType = this.ResolveTypeForMaterialization(collectionElementType, collectionItemTypeName).ElementType; } Type clrCollectionType = WebUtil.GetBackingTypeForCollectionProperty(expectedType, collectionElementType); return(this.clientEdmModel.GetClientTypeAnnotation(clrCollectionType)); }
/// <summary> /// Convert from primitive value to an xml payload string. /// NOTE: We need to pay special attention to DateTimes - if the converted value is going to be used as a content of /// atom:updated or atom:published element we have to ensure it contains information about time zone. At the same time we /// must not touch datetime values that in content or are mapped to custom elements. /// </summary> /// <param name="propertyValue">incoming object value</param> /// <returns>converted value</returns> internal static string ToString(object propertyValue) { Debug.Assert(null != propertyValue, "null should be handled by caller"); PrimitiveType primitiveType; if (PrimitiveType.TryGetPrimitiveType(propertyValue.GetType(), out primitiveType) && primitiveType.TypeConverter != null) { return(primitiveType.TypeConverter.ToString(propertyValue)); } Debug.Assert(false, "new StorageType without update to knownTypes"); return(propertyValue.ToString()); }
internal static string GetEdmType(Type propertyType) { PrimitiveType type; if (!PrimitiveType.TryGetPrimitiveType(propertyType, out type)) { return(null); } if (type.EdmTypeName == null) { throw new NotSupportedException(Strings.ALinq_CantCastToUnsupportedPrimitive(propertyType.Name)); } return(type.EdmTypeName); }
internal static string GetTypeNameForUri(Type type, DataServiceContext context) { PrimitiveType type2; type = Nullable.GetUnderlyingType(type) ?? type; if (PrimitiveType.TryGetPrimitiveType(type, out type2)) { if (!type2.HasReverseMapping) { throw new NotSupportedException(Strings.ALinq_CantCastToUnsupportedPrimitive(type.Name)); } return(type2.EdmTypeName); } return(context.ResolveNameFromType(type) ?? type.FullName); }
internal static bool ToNamedType(string typeName, out Type type) { PrimitiveType type2; type = typeof(string); if (string.IsNullOrEmpty(typeName)) { return(true); } if (PrimitiveType.TryGetPrimitiveType(typeName, out type2)) { type = type2.ClrType; return(true); } return(false); }
internal static bool TryConvertBinaryToByteArray(object binaryValue, out byte[] converted) { Debug.Assert(binaryValue != null, "binaryValue != null"); #if !ASTORIA_LIGHT && !PORTABLELIB Type valueType = binaryValue.GetType(); PrimitiveType ptype; if (PrimitiveType.TryGetPrimitiveType(valueType, out ptype) && valueType == BinaryTypeConverter.BinaryType) { const BindingFlags Flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod; converted = (byte[])valueType.InvokeMember("ToArray", Flags, null, binaryValue, null, CultureInfo.InvariantCulture); return(true); } #endif converted = null; return(false); }
private ODataCollectionValue CreateODataCollection(Type collectionItemType, string propertyName, object value, List <object> visitedComplexTypeObjects) { PrimitiveType type; string edmType; Func <object, object> valueConverter = null; Func <object, ODataComplexValue> func2 = null; WebUtil.ValidateCollection(collectionItemType, value, propertyName); bool flag = PrimitiveType.TryGetPrimitiveType(collectionItemType, out type); ODataCollectionValue value2 = new ODataCollectionValue(); IEnumerable enumerable = (IEnumerable)value; if (flag) { edmType = ClientConvert.GetEdmType(Nullable.GetUnderlyingType(collectionItemType) ?? collectionItemType); if (valueConverter == null) { valueConverter = delegate(object val) { WebUtil.ValidateCollectionItem(val); WebUtil.ValidatePrimitiveCollectionItem(val, propertyName, collectionItemType); return(GetPrimitiveValue(val, collectionItemType)); }; } value2.Items = Util.GetEnumerable <object>(enumerable, valueConverter); } else { edmType = this.requestInfo.ResolveNameFromType(collectionItemType); if (func2 == null) { func2 = delegate(object val) { WebUtil.ValidateCollectionItem(val); WebUtil.ValidateComplexCollectionItem(val, propertyName, collectionItemType); return(this.CreateODataComplexValue(collectionItemType, val, propertyName, true, visitedComplexTypeObjects)); }; } value2.Items = Util.GetEnumerable <ODataComplexValue>(enumerable, func2); } string str2 = (edmType == null) ? null : string.Format(CultureInfo.InvariantCulture, "Collection({0})", new object[] { edmType }); SerializationTypeNameAnnotation annotation = new SerializationTypeNameAnnotation { TypeName = str2 }; value2.SetAnnotation <SerializationTypeNameAnnotation>(annotation); return(value2); }
/// <summary> /// change primtive typeName into non-nullable type /// </summary> /// <param name="typeName">like Edm.String or Edm.Binary</param> /// <param name="type">the mapped output type</param> /// <returns>true if named</returns> internal static bool ToNamedType(string typeName, out Type type) { type = typeof(string); if (String.IsNullOrEmpty(typeName)) { return(true); } else { PrimitiveType ptype; if (PrimitiveType.TryGetPrimitiveType(typeName, out ptype)) { type = ptype.ClrType; return(true); } else { return(false); } } }
private static object GetPrimitiveValue(object propertyValue, Type propertyType) { PrimitiveType type; if (propertyValue == null) { return(null); } PrimitiveType.TryGetPrimitiveType(propertyType, out type); if ((((propertyType == typeof(char)) || (propertyType == typeof(char[]))) || ((propertyType == typeof(Type)) || (propertyType == typeof(Uri)))) || ((propertyType == typeof(XDocument)) || (propertyType == typeof(XElement)))) { return(type.TypeConverter.ToString(propertyValue)); } if (propertyType.FullName == "System.Data.Linq.Binary") { return(((BinaryTypeConverter)type.TypeConverter).ToArray(propertyValue)); } if (type.EdmTypeName == null) { throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_CantCastToUnsupportedPrimitive(propertyType.Name)); } return(propertyValue); }
internal static object ChangeType(string propertyValue, Type propertyType) { PrimitiveType type; if (PrimitiveType.TryGetPrimitiveType(propertyType, out type) && (type.TypeConverter != null)) { try { return(type.TypeConverter.Parse(propertyValue)); } catch (FormatException exception) { propertyValue = (propertyValue.Length == 0) ? "String.Empty" : "String"; throw Error.InvalidOperation(Strings.Deserialize_Current(propertyType.ToString(), propertyValue), exception); } catch (OverflowException exception2) { propertyValue = (propertyValue.Length == 0) ? "String.Empty" : "String"; throw Error.InvalidOperation(Strings.Deserialize_Current(propertyType.ToString(), propertyValue), exception2); } } return(propertyValue); }
/// <summary> /// Creates and returns an ODataCollectionValue from the given value. /// </summary> /// <param name="collectionItemType">The type of the value.</param> /// <param name="propertyName">If the value is a property, then it represents the name of the property. Can be null, for non-property.</param> /// <param name="value">The value.</param> /// <param name="visitedComplexTypeObjects">Set of instances of complex types encountered in the hierarchy. Used to detect cycles.</param> /// <returns>An ODataCollectionValue representing the given value.</returns> internal ODataCollectionValue CreateODataCollection(Type collectionItemType, string propertyName, object value, HashSet <object> visitedComplexTypeObjects) { Debug.Assert(collectionItemType != null, "collectionItemType != null"); WebUtil.ValidateCollection(collectionItemType, value, propertyName); PrimitiveType ptype; bool isCollectionOfPrimitiveTypes = PrimitiveType.TryGetPrimitiveType(collectionItemType, out ptype); ODataCollectionValue collection = new ODataCollectionValue(); IEnumerable enumerablePropertyValue = (IEnumerable)value; string collectionItemTypeName; string collectionTypeName; if (isCollectionOfPrimitiveTypes) { collectionItemTypeName = ClientConvert.GetEdmType(Nullable.GetUnderlyingType(collectionItemType) ?? collectionItemType); collection.Items = Util.GetEnumerable( enumerablePropertyValue, (val) => { WebUtil.ValidateCollectionItem(val); WebUtil.ValidatePrimitiveCollectionItem(val, propertyName, collectionItemType); return(ConvertPrimitiveValueToRecognizedODataType(val, collectionItemType)); }); // TypeName for primitives should be the EDM name since that's what we will be able to look up in the model collectionTypeName = collectionItemTypeName; } else { // Note that the collectionItemTypeName will be null if the context does not have the ResolveName func. collectionItemTypeName = this.requestInfo.ResolveNameFromType(collectionItemType); collection.Items = Util.GetEnumerable( enumerablePropertyValue, (val) => { WebUtil.ValidateCollectionItem(val); WebUtil.ValidateComplexCollectionItem(val, propertyName, collectionItemType); return(this.CreateODataComplexValue(collectionItemType, val, propertyName, true /*isCollectionItem*/, visitedComplexTypeObjects)); }); // TypeName for complex types needs to be the client type name (not the one we resolved above) since it will be looked up in the client model collectionTypeName = collectionItemType.FullName; } // Set the type name to use for client type lookups and validation. Because setting this value can cause validation to occur, we will // only do it for JSON Light, in order to avoid breaking changes with the WCF Data Services 5.0 release, since it was already shipped without this. if (!this.requestInfo.Format.UsingAtom) { collection.TypeName = GetCollectionName(collectionTypeName); } string wireTypeName = GetCollectionName(collectionItemTypeName); collection.SetAnnotation(new SerializationTypeNameAnnotation { TypeName = wireTypeName }); return(collection); }
private EdmTypeCacheValue GetOrCreateEdmTypeInternal(IEdmStructuredType edmBaseType, Type type, PropertyInfo[] keyProperties, bool isEntity, bool?hasProperties) { EdmTypeCacheValue value2; Action <MetadataProviderEdmEntityType> action3 = null; Action <MetadataProviderEdmComplexType> action4 = null; lock (this.clrToEdmTypeCache) { this.clrToEdmTypeCache.TryGetValue(type, out value2); } if (value2 == null) { if (PrimitiveType.IsKnownNullableType(type)) { PrimitiveType type3; PrimitiveType.TryGetPrimitiveType(type, out type3); value2 = new EdmTypeCacheValue(type3.CreateEdmPrimitiveType(), hasProperties); } else { Type type2; if (((type2 = ClientTypeUtil.GetImplementationType(type, typeof(ICollection <>))) != null) && (ClientTypeUtil.GetImplementationType(type, typeof(IDictionary <,>)) == null)) { Type type4 = type2.GetGenericArguments()[0]; value2 = new EdmTypeCacheValue(new EdmCollectionType(this.GetOrCreateEdmTypeInternal(type4).EdmType.ToEdmTypeReference(ClientTypeUtil.CanAssignNull(type4))), hasProperties); } else if (isEntity) { if (action3 == null) { action3 = delegate(MetadataProviderEdmEntityType entityType) { List <IEdmProperty> list = new List <IEdmProperty>(); List <IEdmStructuralProperty> list1 = new List <IEdmStructuralProperty>(); using (IEnumerator <PropertyInfo> enumerator = (from p in ClientTypeUtil.GetPropertiesOnType(type, edmBaseType != null) orderby p.Name select p).GetEnumerator()) { Func <PropertyInfo, bool> predicate = null; while (enumerator.MoveNext()) { PropertyInfo property = enumerator.Current; IEdmProperty item = this.CreateEdmProperty(entityType, property); list.Add(item); if (edmBaseType == null) { if (predicate == null) { predicate = k => (k.DeclaringType == type) && (k.Name == property.Name); } if (keyProperties.Any <PropertyInfo>(predicate)) { list1.Add((IEdmStructuralProperty)item); } } } } foreach (IEdmProperty property2 in list) { entityType.AddProperty(property2); } entityType.AddKeys(list1); }; } Action <MetadataProviderEdmEntityType> propertyLoadAction = action3; value2 = new EdmTypeCacheValue(new MetadataProviderEdmEntityType(CommonUtil.GetModelTypeNamespace(type), CommonUtil.GetModelTypeName(type), (IEdmEntityType)edmBaseType, type.IsAbstract(), false, propertyLoadAction), hasProperties); } else { if (action4 == null) { action4 = delegate(MetadataProviderEdmComplexType complexType) { List <IEdmProperty> list = new List <IEdmProperty>(); foreach (PropertyInfo info in from p in ClientTypeUtil.GetPropertiesOnType(type, edmBaseType != null) orderby p.Name select p) { IEdmProperty item = this.CreateEdmProperty(complexType, info); list.Add(item); } foreach (IEdmProperty property2 in list) { complexType.AddProperty(property2); } }; } Action <MetadataProviderEdmComplexType> action2 = action4; value2 = new EdmTypeCacheValue(new MetadataProviderEdmComplexType(CommonUtil.GetModelTypeNamespace(type), CommonUtil.GetModelTypeName(type), (IEdmComplexType)edmBaseType, type.IsAbstract(), action2), hasProperties); } } IEdmType edmType = value2.EdmType; ClientTypeAnnotation orCreateClientTypeAnnotation = this.GetOrCreateClientTypeAnnotation(edmType, type); edmType.SetClientTypeAnnotation(orCreateClientTypeAnnotation); if ((edmType.TypeKind == EdmTypeKind.Entity) || (edmType.TypeKind == EdmTypeKind.Complex)) { IEdmStructuredType edmStructuredType = edmType as IEdmStructuredType; this.SetMimeTypeForProperties(edmStructuredType); } lock (this.clrToEdmTypeCache) { EdmTypeCacheValue value3; if (this.clrToEdmTypeCache.TryGetValue(type, out value3)) { return(value3); } this.clrToEdmTypeCache.Add(type, value2); } } return(value2); }
private EdmTypeCacheValue GetOrCreateEdmTypeInternal(IEdmStructuredType edmBaseType, Type type, PropertyInfo[] keyProperties, bool isEntity, bool?hasProperties) { Debug.Assert(type != null, "type != null"); Debug.Assert(keyProperties != null, "keyProperties != null"); EdmTypeCacheValue cachedEdmType; lock (this.clrToEdmTypeCache) { this.clrToEdmTypeCache.TryGetValue(type, out cachedEdmType); } if (cachedEdmType == null) { Type collectionType; if (PrimitiveType.IsKnownNullableType(type)) { PrimitiveType primitiveType; PrimitiveType.TryGetPrimitiveType(type, out primitiveType); Debug.Assert(primitiveType != null, "primitiveType != null"); cachedEdmType = new EdmTypeCacheValue(primitiveType.CreateEdmPrimitiveType(), hasProperties); } else if ((collectionType = ClientTypeUtil.GetImplementationType(type, typeof(ICollection <>))) != null && ClientTypeUtil.GetImplementationType(type, typeof(IDictionary <,>)) == null) { // Collection Type Type elementType = collectionType.GetGenericArguments()[0]; IEdmType itemType = this.GetOrCreateEdmTypeInternal(elementType).EdmType; // Note that while collection of a collection is not allowed, we cannot throw here since it's a breaking change. // We will throw during SaveChanges() and we have unit test validating the error case. Debug.Assert( itemType.TypeKind == EdmTypeKind.Entity || itemType.TypeKind == EdmTypeKind.Complex || itemType.TypeKind == EdmTypeKind.Primitive || itemType.TypeKind == EdmTypeKind.Collection, "itemType.TypeKind == EdmTypeKind.Entity || itemType.TypeKind == EdmTypeKind.Complex || itemType.TypeKind == EdmTypeKind.Primitive || itemType.TypeKind == EdmTypeKind.Collection"); cachedEdmType = new EdmTypeCacheValue(new EdmCollectionType(itemType.ToEdmTypeReference(ClientTypeUtil.CanAssignNull(elementType))), hasProperties); } else { if (isEntity) { Action <EdmEntityTypeWithDelayLoadedProperties> delayLoadEntityProperties = (entityType) => { // Create properties without modifying the entityType. // This will leave entityType intact in case of an exception during loading. List <IEdmProperty> loadedProperties = new List <IEdmProperty>(); List <IEdmStructuralProperty> loadedKeyProperties = new List <IEdmStructuralProperty>(); foreach (PropertyInfo property in ClientTypeUtil.GetPropertiesOnType(type, /*declaredOnly*/ edmBaseType != null).OrderBy(p => p.Name)) { IEdmProperty edmProperty = this.CreateEdmProperty((EdmStructuredType)entityType, property); loadedProperties.Add(edmProperty); if (edmBaseType == null && keyProperties.Any(k => k.DeclaringType == type && k.Name == property.Name)) { Debug.Assert(edmProperty.PropertyKind == EdmPropertyKind.Structural, "edmProperty.PropertyKind == EdmPropertyKind.Structural"); Debug.Assert(edmProperty.Type.TypeKind() == EdmTypeKind.Primitive, "edmProperty.Type.TypeKind() == EdmTypeKind.Primitive"); loadedKeyProperties.Add((IEdmStructuralProperty)edmProperty); } } // Now add properties to the entityType. foreach (IEdmProperty property in loadedProperties) { entityType.AddProperty(property); } entityType.AddKeys(loadedKeyProperties); }; // Creating an entity type Debug.Assert(edmBaseType == null || edmBaseType.TypeKind == EdmTypeKind.Entity, "baseType == null || baseType.TypeKind == EdmTypeKind.Entity"); cachedEdmType = new EdmTypeCacheValue( new EdmEntityTypeWithDelayLoadedProperties(CommonUtil.GetModelTypeNamespace(type), CommonUtil.GetModelTypeName(type), (IEdmEntityType)edmBaseType, c.PlatformHelper.IsAbstract(type), false /*isOpen*/, delayLoadEntityProperties), hasProperties); } else { Action <EdmComplexTypeWithDelayLoadedProperties> delayLoadComplexProperties = (complexType) => { // Create properties without modifying the complexType. // This will leave complexType intact in case of an exception during loading. List <IEdmProperty> loadedProperties = new List <IEdmProperty>(); foreach (PropertyInfo property in ClientTypeUtil.GetPropertiesOnType(type, /*declaredOnly*/ edmBaseType != null).OrderBy(p => p.Name)) { IEdmProperty edmProperty = this.CreateEdmProperty(complexType, property); loadedProperties.Add(edmProperty); } // Now add properties to the complexType. foreach (IEdmProperty property in loadedProperties) { complexType.AddProperty(property); } }; // Creating a complex type Debug.Assert(edmBaseType == null || edmBaseType.TypeKind == EdmTypeKind.Complex, "baseType == null || baseType.TypeKind == EdmTypeKind.Complex"); cachedEdmType = new EdmTypeCacheValue( new EdmComplexTypeWithDelayLoadedProperties(CommonUtil.GetModelTypeNamespace(type), CommonUtil.GetModelTypeName(type), (IEdmComplexType)edmBaseType, c.PlatformHelper.IsAbstract(type), delayLoadComplexProperties), hasProperties); } } Debug.Assert(cachedEdmType != null, "cachedEdmType != null"); IEdmType edmType = cachedEdmType.EdmType; ClientTypeAnnotation clientTypeAnnotation = this.GetOrCreateClientTypeAnnotation(edmType, type); this.SetClientTypeAnnotation(edmType, clientTypeAnnotation); if (edmType.TypeKind == EdmTypeKind.Entity || edmType.TypeKind == EdmTypeKind.Complex) { IEdmStructuredType edmStructuredType = edmType as IEdmStructuredType; Debug.Assert(edmStructuredType != null, "edmStructuredType != null"); this.SetMimeTypeForProperties(edmStructuredType); } // Need to cache the type before loading the properties so we don't stack overflow because // loading the property can trigger calls to GetOrCreateEdmType on the same type. lock (this.clrToEdmTypeCache) { EdmTypeCacheValue existing; if (this.clrToEdmTypeCache.TryGetValue(type, out existing)) { cachedEdmType = existing; } else { this.clrToEdmTypeCache.Add(type, cachedEdmType); } } } return(cachedEdmType); }
internal static bool IsBinaryValue(object value) { PrimitiveType type; return(PrimitiveType.TryGetPrimitiveType(value.GetType(), out type) && (value.GetType() == BinaryTypeConverter.BinaryType)); }