private Expression GetPredicateBody(HttpRequestMessage request, ParameterExpression param) { Expression workingExpr = null; var type = param.Type; var queryPairs = request.GetQueryNameValuePairs(); foreach (var queryPair in queryPairs) { if (String.IsNullOrWhiteSpace(queryPair.Key)) { continue; } var prop = _modelManager.GetPropertyForJsonKey(type, queryPair.Key); if (prop != null) { var propertyType = prop.PropertyType; var queryValue = queryPair.Value; if (string.IsNullOrWhiteSpace(queryValue)) { queryValue = null; } Expression expr = null; if (propertyType == typeof(String)) { if (String.IsNullOrWhiteSpace(queryValue)) { Expression propertyExpr = Expression.Property(param, prop); expr = Expression.Equal(propertyExpr, Expression.Constant(null)); } else { Expression propertyExpr = Expression.Property(param, prop); expr = Expression.Equal(propertyExpr, Expression.Constant(queryValue)); } } else if (propertyType == typeof(Boolean)) { bool value; expr = bool.TryParse(queryValue, out value) ? GetPropertyExpression(value, prop, param) : Expression.Constant(false); } else if (propertyType == typeof(Boolean?)) { bool tmp; var value = bool.TryParse(queryValue, out tmp) ? tmp : (bool?)null; expr = GetPropertyExpression(value, prop, param); } else if (propertyType == typeof(SByte)) { SByte value; expr = SByte.TryParse(queryValue, out value) ? GetPropertyExpression(value, prop, param) : Expression.Constant(false); } else if (propertyType == typeof(SByte?)) { SByte tmp; var value = SByte.TryParse(queryValue, out tmp) ? tmp : (SByte?)null; expr = GetPropertyExpression(value, prop, param); } else if (propertyType == typeof(Byte)) { Byte value; expr = Byte.TryParse(queryValue, out value) ? GetPropertyExpression(value, prop, param) : Expression.Constant(false); } else if (propertyType == typeof(Byte?)) { Byte tmp; var value = Byte.TryParse(queryValue, out tmp) ? tmp : (Byte?)null; expr = GetPropertyExpression(value, prop, param); } else if (propertyType == typeof(Int16)) { Int16 value; expr = Int16.TryParse(queryValue, out value) ? GetPropertyExpression(value, prop, param) : Expression.Constant(false); } else if (propertyType == typeof(Int16?)) { Int16 tmp; var value = Int16.TryParse(queryValue, out tmp) ? tmp : (Int16?)null; expr = GetPropertyExpression(value, prop, param); } else if (propertyType == typeof(UInt16)) { UInt16 value; expr = UInt16.TryParse(queryValue, out value) ? GetPropertyExpression(value, prop, param) : Expression.Constant(false); } else if (propertyType == typeof(UInt16?)) { UInt16 tmp; var value = UInt16.TryParse(queryValue, out tmp) ? tmp : (UInt16?)null; expr = GetPropertyExpression(value, prop, param); } else if (propertyType == typeof(Int32)) { Int32 value; expr = Int32.TryParse(queryValue, out value) ? GetPropertyExpression(value, prop, param) : Expression.Constant(false); } else if (propertyType == typeof(Int32?)) { Int32 tmp; var value = Int32.TryParse(queryValue, out tmp) ? tmp : (Int32?)null; expr = GetPropertyExpression(value, prop, param); } else if (propertyType == typeof(UInt32)) { UInt32 value; expr = UInt32.TryParse(queryValue, out value) ? GetPropertyExpression(value, prop, param) : Expression.Constant(false); } else if (propertyType == typeof(UInt32?)) { UInt32 tmp; var value = UInt32.TryParse(queryValue, out tmp) ? tmp : (UInt32?)null; expr = GetPropertyExpression(value, prop, param); } else if (propertyType == typeof(Int64)) { Int64 value; expr = Int64.TryParse(queryValue, out value) ? GetPropertyExpression(value, prop, param) : Expression.Constant(false); } else if (propertyType == typeof(Int64?)) { Int64 tmp; var value = Int64.TryParse(queryValue, out tmp) ? tmp : (Int64?)null; expr = GetPropertyExpression(value, prop, param); } else if (propertyType == typeof(UInt64)) { UInt64 value; expr = UInt64.TryParse(queryValue, out value) ? GetPropertyExpression(value, prop, param) : Expression.Constant(false); } else if (propertyType == typeof(UInt64?)) { UInt64 tmp; var value = UInt64.TryParse(queryValue, out tmp) ? tmp : (UInt64?)null; expr = GetPropertyExpression(value, prop, param); } else if (propertyType == typeof(Single)) { Single value; expr = Single.TryParse(queryValue, out value) ? GetPropertyExpression(value, prop, param) : Expression.Constant(false); } else if (propertyType == typeof(Single?)) { Single tmp; var value = Single.TryParse(queryValue, out tmp) ? tmp : (Single?)null; expr = GetPropertyExpression(value, prop, param); } else if (propertyType == typeof(Double)) { Double value; expr = Double.TryParse(queryValue, out value) ? GetPropertyExpression(value, prop, param) : Expression.Constant(false); } else if (propertyType == typeof(Double?)) { Double tmp; var value = Double.TryParse(queryValue, out tmp) ? tmp : (Double?)null; expr = GetPropertyExpression(value, prop, param); } else if (propertyType == typeof(Decimal)) { Decimal value; expr = Decimal.TryParse(queryValue, out value) ? GetPropertyExpression(value, prop, param) : Expression.Constant(false); } else if (propertyType == typeof(Decimal?)) { Decimal tmp; var value = Decimal.TryParse(queryValue, out tmp) ? tmp : (Decimal?)null; expr = GetPropertyExpression(value, prop, param); } else if (propertyType == typeof(DateTime)) { DateTime value; expr = DateTime.TryParse(queryValue, out value) ? GetPropertyExpression(value, prop, param) : Expression.Constant(false); } else if (propertyType == typeof(DateTime?)) { DateTime tmp; var value = DateTime.TryParse(queryValue, out tmp) ? tmp : (DateTime?)null; expr = GetPropertyExpression(value, prop, param); } else if (propertyType == typeof(DateTimeOffset)) { DateTimeOffset value; expr = DateTimeOffset.TryParse(queryValue, out value) ? GetPropertyExpression <DateTimeOffset>(value, prop, param) : Expression.Constant(false); } else if (propertyType == typeof(DateTimeOffset?)) { DateTimeOffset tmp; var value = DateTimeOffset.TryParse(queryValue, out tmp) ? tmp : (DateTimeOffset?)null; expr = GetPropertyExpression(value, prop, param); } else if (propertyType.IsEnum) { int value; expr = (int.TryParse(queryValue, out value) && Enum.IsDefined(propertyType, value)) ? GetEnumPropertyExpression(value, prop, param) : Expression.Constant(false); } else if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable <>) && propertyType.GenericTypeArguments[0].IsEnum) { int tmp; var value = int.TryParse(queryValue, out tmp) ? tmp : (int?)null; expr = GetEnumPropertyExpression(value, prop, param); } else { // See if it is a relationship property if (_modelManager.IsSerializedAsMany(propertyType)) { var elementType = _modelManager.GetElementType(propertyType); PropertyInfo relatedIdProperty; try { relatedIdProperty = _modelManager.GetIdProperty(elementType); } catch (InvalidOperationException) { relatedIdProperty = null; } if (relatedIdProperty != null) { var propertyExpr = Expression.Property(param, prop); if (string.IsNullOrWhiteSpace(queryValue)) { var leftExpr = Expression.Equal(propertyExpr, Expression.Constant(null)); var asQueryableCallExpr = Expression.Call( typeof(Queryable), "AsQueryable", new[] { elementType }, propertyExpr); var anyCallExpr = Expression.Call( typeof(Queryable), "Any", new[] { elementType }, asQueryableCallExpr); var rightExpr = Expression.Not(anyCallExpr); expr = Expression.OrElse(leftExpr, rightExpr); } else { var leftExpr = Expression.NotEqual(propertyExpr, Expression.Constant(null)); var idValue = queryValue.Trim(); var idExpr = Expression.Constant(idValue); var anyParam = Expression.Parameter(elementType); var relatedIdPropertyExpr = Expression.Property(anyParam, relatedIdProperty); var relatedIdPropertyEqualsIdExpr = Expression.Equal(relatedIdPropertyExpr, idExpr); var anyPredicateExpr = Expression.Lambda(relatedIdPropertyEqualsIdExpr, anyParam); var asQueryableCallExpr = Expression.Call( typeof(Queryable), "AsQueryable", new[] { elementType }, propertyExpr); var rightExpr = Expression.Call( typeof(Queryable), "Any", new[] { elementType }, asQueryableCallExpr, anyPredicateExpr); expr = Expression.AndAlso(leftExpr, rightExpr); } } } else { PropertyInfo relatedIdProperty; try { relatedIdProperty = _modelManager.GetIdProperty(propertyType); } catch (InvalidOperationException) { relatedIdProperty = null; } if (relatedIdProperty != null) { var propertyExpr = Expression.Property(param, prop); if (string.IsNullOrWhiteSpace(queryValue)) { expr = Expression.Equal(propertyExpr, Expression.Constant(null)); } else { var leftExpr = Expression.NotEqual(propertyExpr, Expression.Constant(null)); var idValue = queryValue.Trim(); var idExpr = Expression.Constant(idValue); var relatedIdPropertyExpr = Expression.Property(propertyExpr, relatedIdProperty); var rightExpr = Expression.Equal(relatedIdPropertyExpr, idExpr); expr = Expression.AndAlso(leftExpr, rightExpr); } } } } if (expr == null) { expr = Expression.Constant(true); } workingExpr = workingExpr == null ? expr : Expression.AndAlso(workingExpr, expr); } } return(workingExpr ?? Expression.Constant(true)); // No filters, so return everything }
private Type GetSingleType(Type type)//dynamic value = null) { return(_modelManager.IsSerializedAsMany(type) ? _modelManager.GetElementType(type) : type); }