public static IEnumerable <MetadataItem> GetEnumMembers(EdmType enumType) { Requires <ArgumentNullException> .IsNotNull(enumType); var membersProperty = enumType.GetType().GetProperty("Members"); return(membersProperty != null ? membersProperty.GetValue(enumType, null) as IEnumerable <MetadataItem> : Enumerable.Empty <MetadataItem>()); }
/// <summary> /// /// </summary> /// <param name="property"></param> /// <param name="getElementType"></param> /// <returns></returns> private CodeTypeReference GetType(EdmProperty property, bool getElementType) { PropertyTypeReferences types = default(PropertyTypeReferences); EdmType propertyType = property.TypeUsage.EdmType; // Initialize types if (Helper.IsPrimitiveType(propertyType)) { types = new PropertyTypeReferences(TypeReference, (PrimitiveType)propertyType); } else if (Helper.IsComplexType(propertyType)) { types = new PropertyTypeReferences(TypeReference, (ComplexType)propertyType, Generator); } else if (Helper.IsCollectionType(propertyType)) { TypeUsage typeUsage = ((CollectionType)propertyType).TypeUsage; if (Helper.IsPrimitiveType(typeUsage.EdmType)) { types = new PropertyTypeReferences(TypeReference, (PrimitiveType)typeUsage.EdmType, GetCollectionKind(property.TypeUsage)); } else { Debug.Assert(Helper.IsComplexType(typeUsage.EdmType)); types = new PropertyTypeReferences(TypeReference, (ComplexType)typeUsage.EdmType, GetCollectionKind(property.TypeUsage), Generator); } } else { // shouldn't be able to get here.... Debug.Fail("Unexpected Property.Type type: " + propertyType.GetType()); } // Set types, or retrieve existing types if they have been set in the interim // Don't cache Collection types since CollectionKind is really a facet and //it is not part of the key we are using for the dictionary used to cache. if (!Helper.IsCollectionType(propertyType)) { Debug.Assert(types.NonNullable != null && types.Nullable != null, "did you forget to set the types variable?"); } if (property.Nullable) { return(types.Nullable); } else { return(types.NonNullable); } }
internal static void ReadAndUpdateTableEntityWithEdmTypeResolver(ITableEntity entity, Dictionary <string, string> entityAttributes, EntityReadFlags flags, Func <string, string, string, string, EdmType> propertyResolver, OperationContext ctx) { Dictionary <string, EntityProperty> entityProperties = (flags & EntityReadFlags.Properties) > 0 ? new Dictionary <string, EntityProperty>() : null; Dictionary <string, EdmType> propertyResolverDictionary = null; // Try to add the dictionary to the cache only if it is not a DynamicTableEntity. If DisablePropertyResolverCache is true, then just use reflection and generate dictionaries for each entity. if (entity.GetType() != typeof(DynamicTableEntity)) { #if WINDOWS_DESKTOP && !WINDOWS_PHONE if (!TableEntity.DisablePropertyResolverCache) { propertyResolverDictionary = TableEntity.PropertyResolverCache.GetOrAdd(entity.GetType(), TableOperationHttpResponseParsers.CreatePropertyResolverDictionary); } else { Logger.LogVerbose(ctx, SR.PropertyResolverCacheDisabled); propertyResolverDictionary = TableOperationHttpResponseParsers.CreatePropertyResolverDictionary(entity.GetType()); } #else propertyResolverDictionary = TableOperationHttpResponseParsers.CreatePropertyResolverDictionary(entity.GetType()); #endif } if (flags > 0) { foreach (KeyValuePair <string, string> prop in entityAttributes) { if (prop.Key == TableConstants.PartitionKey) { entity.PartitionKey = (string)prop.Value; } else if (prop.Key == TableConstants.RowKey) { entity.RowKey = (string)prop.Value; } else if (prop.Key == TableConstants.Timestamp) { if ((flags & EntityReadFlags.Timestamp) == 0) { continue; } entity.Timestamp = DateTime.Parse(prop.Value, CultureInfo.InvariantCulture); } else if ((flags & EntityReadFlags.Properties) > 0) { if (propertyResolver != null) { Logger.LogVerbose(ctx, SR.UsingUserProvidedPropertyResolver); try { EdmType type = propertyResolver(entity.PartitionKey, entity.RowKey, prop.Key, prop.Value); Logger.LogVerbose(ctx, SR.AttemptedEdmTypeForTheProperty, prop.Key, type.GetType().ToString()); try { entityProperties.Add(prop.Key, EntityProperty.CreateEntityPropertyFromObject(prop.Value, type.GetType())); } catch (FormatException ex) { throw new StorageException(string.Format(CultureInfo.InvariantCulture, SR.FailParseProperty, prop.Key, prop.Value, type.ToString()), ex) { IsRetryable = false }; } } catch (StorageException) { throw; } catch (Exception ex) { throw new StorageException(SR.PropertyResolverThrewError, ex) { IsRetryable = false }; } } else if (entity.GetType() != typeof(DynamicTableEntity)) { EdmType edmType; Logger.LogVerbose(ctx, SR.UsingDefaultPropertyResolver); if (propertyResolverDictionary != null) { propertyResolverDictionary.TryGetValue(prop.Key, out edmType); Logger.LogVerbose(ctx, SR.AttemptedEdmTypeForTheProperty, prop.Key, edmType); entityProperties.Add(prop.Key, EntityProperty.CreateEntityPropertyFromObject(prop.Value, edmType)); } } else { Logger.LogVerbose(ctx, SR.NoPropertyResolverAvailable); entityProperties.Add(prop.Key, EntityProperty.CreateEntityPropertyFromObject(prop.Value, typeof(string))); } } } if ((flags & EntityReadFlags.Properties) > 0) { entity.ReadEntity(entityProperties, ctx); } } }
internal static void ReadAndUpdateTableEntityWithEdmTypeResolver(ITableEntity entity, Dictionary <string, string> entityAttributes, EntityReadFlags flags, Func <string, string, string, string, EdmType> propertyResolver, OperationContext ctx) { Dictionary <string, EntityProperty> dictionary = ((flags & EntityReadFlags.Properties) > (EntityReadFlags)0) ? new Dictionary <string, EntityProperty>() : null; Dictionary <string, EdmType> dictionary2 = null; if (entity.GetType() != typeof(DynamicTableEntity)) { if (!TableEntity.DisablePropertyResolverCache) { dictionary2 = TableEntity.PropertyResolverCache.GetOrAdd(entity.GetType(), CreatePropertyResolverDictionary); } else { Logger.LogVerbose(ctx, "Property resolver cache is disabled."); dictionary2 = CreatePropertyResolverDictionary(entity.GetType()); } } if (flags > (EntityReadFlags)0) { foreach (KeyValuePair <string, string> entityAttribute in entityAttributes) { if (entityAttribute.Key == "PartitionKey") { entity.PartitionKey = entityAttribute.Value; } else if (entityAttribute.Key == "RowKey") { entity.RowKey = entityAttribute.Value; } else if (entityAttribute.Key == "Timestamp") { if ((flags & EntityReadFlags.Timestamp) != 0) { entity.Timestamp = DateTime.Parse(entityAttribute.Value, CultureInfo.InvariantCulture); } } else if ((flags & EntityReadFlags.Properties) > (EntityReadFlags)0) { if (propertyResolver != null) { Logger.LogVerbose(ctx, "Using the property resolver provided via TableRequestOptions to deserialize the entity."); try { EdmType edmType = propertyResolver(entity.PartitionKey, entity.RowKey, entityAttribute.Key, entityAttribute.Value); Logger.LogVerbose(ctx, "Attempting to deserialize '{0}' as type '{1}'", entityAttribute.Key, edmType.GetType().ToString()); try { dictionary.Add(entityAttribute.Key, EntityProperty.CreateEntityPropertyFromObject(entityAttribute.Value, edmType.GetType())); } catch (FormatException innerException) { throw new StorageException(string.Format(CultureInfo.InvariantCulture, "Failed to parse property '{0}' with value '{1}' as type '{2}'", entityAttribute.Key, entityAttribute.Value, edmType.ToString()), innerException) { IsRetryable = false }; } } catch (StorageException) { throw; } catch (Exception innerException2) { throw new StorageException("The custom property resolver delegate threw an exception. Check the inner exception for more details.", innerException2) { IsRetryable = false }; } } else if (entity.GetType() != typeof(DynamicTableEntity)) { Logger.LogVerbose(ctx, "Using the default property resolver to deserialize the entity."); if (dictionary2 != null) { dictionary2.TryGetValue(entityAttribute.Key, out EdmType value); Logger.LogVerbose(ctx, "Attempting to deserialize '{0}' as type '{1}'", entityAttribute.Key, value); dictionary.Add(entityAttribute.Key, EntityProperty.CreateEntityPropertyFromObject(entityAttribute.Value, value)); } } else { Logger.LogVerbose(ctx, "No property resolver available. Deserializing the entity properties as strings."); dictionary.Add(entityAttribute.Key, EntityProperty.CreateEntityPropertyFromObject(entityAttribute.Value, typeof(string))); } } } if ((flags & EntityReadFlags.Properties) > (EntityReadFlags)0) { entity.ReadEntity(dictionary, ctx); } } }
/// <summary> /// Determine a CLR Type to use a property descriptro form an EDM TypeUsage /// </summary> /// <param name="typeUsage">The EDM TypeUsage containing metadata about the type</param> /// <returns>A CLR type that represents that EDM type</returns> private Type DetermineClrType(TypeUsage typeUsage) { Type result = null; EdmType edmType = typeUsage.EdmType; switch (edmType.BuiltInTypeKind) { case BuiltInTypeKind.EntityType: case BuiltInTypeKind.ComplexType: result = edmType.ClrType; break; case BuiltInTypeKind.RefType: result = typeof(EntityKey); break; case BuiltInTypeKind.CollectionType: TypeUsage elementTypeUse = ((CollectionType)edmType).TypeUsage; result = DetermineClrType(elementTypeUse); result = typeof(IEnumerable <>).MakeGenericType(result); break; case BuiltInTypeKind.PrimitiveType: case BuiltInTypeKind.EnumType: result = edmType.ClrType; Facet nullable; if (result.IsValueType && typeUsage.Facets.TryGetValue(DbProviderManifest.NullableFacetName, false, out nullable) && ((bool)nullable.Value)) { result = typeof(Nullable <>).MakeGenericType(result); } break; case BuiltInTypeKind.RowType: result = typeof(IDataRecord); break; default: Debug.Fail(string.Format(CultureInfo.CurrentCulture, "The type {0} was not the expected scalar, enumeration, collection, structural, nominal, or reference type.", edmType.GetType())); break; } return(result); }