/// <summary> /// Generates a Conditional Expression that will retrieve the given entity value by type and set it into the current property. /// </summary> /// <param name="type">The entity type</param> /// <param name="property">The property to deserialize into</param> /// <param name="instanceParam">An Expression that represents the entity instance</param> /// <param name="currentEntityProperty">An Expression that represents the current EntityProperty expression</param> /// <returns></returns> private static Expression GeneratePropertyReadExpressionByType(Type type, PropertyInfo property, Expression instanceParam, Expression currentEntityProperty) { if (property.PropertyType == typeof(string)) { return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.String)), Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_StringPI.FindGetProp()))); } else if (property.PropertyType == typeof(byte[])) { return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Binary)), Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_BinaryPI.FindGetProp()))); } else if (property.PropertyType == typeof(bool?)) { return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Boolean)), Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_BoolPI.FindGetProp()))); } else if (property.PropertyType == typeof(bool)) { MethodInfo hasValuePI = typeof(bool?).FindProperty("HasValue").FindGetProp(); MethodInfo valuePI = typeof(bool?).FindProperty("Value").FindGetProp(); return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Boolean)), Expression.IfThen(Expression.IsTrue(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_BoolPI.FindGetProp()), hasValuePI)), Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_BoolPI.FindGetProp()), valuePI)))); } else if (property.PropertyType == typeof(DateTime?)) { MethodInfo hasValuePI = typeof(DateTimeOffset?).FindProperty("HasValue").FindGetProp(); MethodInfo valuePI = typeof(DateTimeOffset?).FindProperty("Value").FindGetProp(); MethodInfo utcDateTimePI = typeof(DateTimeOffset).FindProperty("UtcDateTime").FindGetProp(); ParameterExpression tempVal = Expression.Variable(typeof(DateTime?), "tempVal"); ConditionalExpression valToSetExpr = Expression.IfThenElse( // entityProperty.DateTimeOffsetValue.HasValue Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DateTimeOffsetPI.FindGetProp()), hasValuePI), // then //entityProperty.DateTimeOffsetValue.Value.UtcDateTime Expression.Assign(tempVal, Expression.TypeAs(Expression.Call(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DateTimeOffsetPI.FindGetProp()), valuePI), utcDateTimePI), typeof(DateTime?))), // else Expression.Assign(tempVal, Expression.TypeAs(Expression.Constant(null), typeof(DateTime?)))); return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.DateTime)), Expression.Block(new[] { tempVal }, valToSetExpr, Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), tempVal))); } else if (property.PropertyType == typeof(DateTime)) { MethodInfo valuePI = typeof(DateTimeOffset?).FindProperty("Value").FindGetProp(); MethodInfo utcDateTimePI = typeof(DateTimeOffset).FindProperty("UtcDateTime").FindGetProp(); return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.DateTime)), Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), // entityProperty.DateTimeOffsetValue.Value.UtcDateTime Expression.Call(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DateTimeOffsetPI.FindGetProp()), valuePI), utcDateTimePI))); } else if (property.PropertyType == typeof(DateTimeOffset?)) { return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.DateTime)), Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_DateTimeOffsetPI.FindGetProp()))); } else if (property.PropertyType == typeof(DateTimeOffset)) { MethodInfo hasValuePI = typeof(DateTimeOffset?).FindProperty("HasValue").FindGetProp(); MethodInfo valuePI = typeof(DateTimeOffset?).FindProperty("Value").FindGetProp(); return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.DateTime)), Expression.IfThen(Expression.IsTrue(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DateTimeOffsetPI.FindGetProp()), hasValuePI)), Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DateTimeOffsetPI.FindGetProp()), valuePI)))); } else if (property.PropertyType == typeof(double?)) { return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Double)), Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_DoublePI.FindGetProp()))); } else if (property.PropertyType == typeof(double)) { MethodInfo hasValuePI = typeof(double?).FindProperty("HasValue").FindGetProp(); MethodInfo valuePI = typeof(double?).FindProperty("Value").FindGetProp(); return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Double)), Expression.IfThen(Expression.IsTrue(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DoublePI.FindGetProp()), hasValuePI)), Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_DoublePI.FindGetProp()), valuePI)))); } else if (property.PropertyType == typeof(Guid?)) { return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Guid)), Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_GuidPI.FindGetProp()))); } else if (property.PropertyType == typeof(Guid)) { MethodInfo hasValuePI = typeof(Guid?).FindProperty("HasValue").FindGetProp(); MethodInfo valuePI = typeof(Guid?).FindProperty("Value").FindGetProp(); return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Guid)), Expression.IfThen(Expression.IsTrue(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_GuidPI.FindGetProp()), hasValuePI)), Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_GuidPI.FindGetProp()), valuePI)))); } else if (property.PropertyType == typeof(int?)) { return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Int32)), Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_Int32PI.FindGetProp()))); } else if (property.PropertyType == typeof(int)) { MethodInfo hasValuePI = typeof(int?).FindProperty("HasValue").FindGetProp(); MethodInfo valuePI = typeof(int?).FindProperty("Value").FindGetProp(); return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Int32)), Expression.IfThen(Expression.IsTrue(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_Int32PI.FindGetProp()), hasValuePI)), Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_Int32PI.FindGetProp()), valuePI)))); } else if (property.PropertyType == typeof(long?)) { return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Int64)), Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(currentEntityProperty, EntityProperty_Int64PI.FindGetProp()))); } else if (property.PropertyType == typeof(long)) { MethodInfo hasValuePI = typeof(long?).FindProperty("HasValue").FindGetProp(); MethodInfo valuePI = typeof(long?).FindProperty("Value").FindGetProp(); return Expression.IfThen(Expression.Equal(Expression.Call(currentEntityProperty, EntityProperty_PropTypeGetter), Expression.Constant(EdmType.Int64)), Expression.IfThen(Expression.IsTrue(Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_Int64PI.FindGetProp()), hasValuePI)), Expression.Call(Expression.Convert(instanceParam, type), property.FindSetProp(), Expression.Call(Expression.Call(currentEntityProperty, EntityProperty_Int64PI.FindGetProp()), valuePI)))); } return null; }
/// <summary> /// Determines if the given property should be skipped based on its name, if it exposes a public getter and setter, and if the IgnoreAttribute is not defined. /// </summary> /// <param name="property">The PropertyInfo of the property to check</param> /// <param name="operationContext">An <see cref="OperationContext"/> object used to track the execution of the operation.</param> /// <returns>True if the property should be skipped, false otherwise. </returns> private static bool ShouldSkipProperty(PropertyInfo property, OperationContext operationContext) { // reserved properties string propName = property.Name; if (propName == TableConstants.PartitionKey || propName == TableConstants.RowKey || propName == TableConstants.Timestamp || propName == TableConstants.Etag) { return true; } MethodInfo setter = property.FindSetProp(); MethodInfo getter = property.FindGetProp(); // Enforce public getter / setter if (setter == null || !setter.IsPublic || getter == null || !getter.IsPublic) { Logger.LogInformational(operationContext, SR.TraceNonPublicGetSet, property.Name); return true; } // Skip static properties if (setter.IsStatic) { return true; } // properties with [IgnoreAttribute] #if WINDOWS_RT if (property.GetCustomAttribute(typeof(IgnorePropertyAttribute)) != null) #else if (Attribute.IsDefined(property, typeof(IgnorePropertyAttribute))) #endif { Logger.LogInformational(operationContext, SR.TraceIgnoreAttribute, property.Name); return true; } return false; }