Ejemplo n.º 1
0
        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>());
        }
Ejemplo n.º 2
0
        /// <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);
        }