/// <summary> /// create greater than or equal expression ( operator ">=" or "=ge=" ) /// </summary> /// <param name="parameter"></param> /// <param name="context"></param> /// <param name="jsonNamingPolicy"></param> /// <typeparam name="T"></typeparam> /// <returns></returns> public static Expression <Func <T, bool> > GetGeExpression <T>(ParameterExpression parameter, RSqlQueryParser.ComparisonContext context, JsonNamingPolicy jsonNamingPolicy = null) { var expressionValue = GetSelector <T>(parameter, context, jsonNamingPolicy); if (!RSqlQueryGetValueHelper.IsLowerOrGreaterComparisonType(expressionValue.Property.PropertyType)) { throw new ComparisonInvalidComparatorSelectionException(context); } var value = GetUniqueValue <T>(parameter, expressionValue, context, jsonNamingPolicy); var expression = value is ExpressionValue valueExp1 ? valueExp1.Expression : Expression.Constant(value, expressionValue.Property.PropertyType); if (value is ExpressionValue valueExp2 && valueExp2.Property.PropertyType != expressionValue.Property.PropertyType) { throw new ComparisonInvalidMatchTypeException(context); } return(Expression.Lambda <Func <T, bool> >(Expression.GreaterThanOrEqual( expressionValue.Expression, expression), parameter)); }
/// <summary> /// extract the unique value /// </summary> /// <param name="parameter"></param> /// <param name="expressionValue"></param> /// <param name="context"></param> /// <param name="jsonNamingPolicy"></param> /// <typeparam name="T"></typeparam> /// <returns></returns> /// <exception cref="ComparisonNotEnoughArgumentException"></exception> /// <exception cref="ComparisonTooManyArgumentException"></exception> private static object GetUniqueValue <T>(ParameterExpression parameter, ExpressionValue expressionValue, RSqlQueryParser.ComparisonContext context, JsonNamingPolicy jsonNamingPolicy = null) { var value = context.arguments().value(); if (value.Length > 1) { throw new ComparisonTooManyArgumentException(context); } return(RSqlQueryGetValueHelper.GetValue <T>(parameter, expressionValue, context, jsonNamingPolicy)); }
/// <summary> /// create equal expression ( operator "==" or "=eq=" ) /// </summary> /// <param name="parameter"></param> /// <param name="context"></param> /// <param name="jsonNamingPolicy"></param> /// <typeparam name="T"></typeparam> /// <returns></returns> public static Expression <Func <T, bool> > GetEqExpression <T>(ParameterExpression parameter, RSqlQueryParser.ComparisonContext context, JsonNamingPolicy jsonNamingPolicy = null) { var expressionValue = GetSelector <T>(parameter, context, jsonNamingPolicy); if (!RSqlQueryGetValueHelper.IsEqualComparisonType(expressionValue.Property.PropertyType)) { throw new ComparisonInvalidComparatorSelectionException(context); } var value = GetUniqueValue <T>(parameter, expressionValue, context, jsonNamingPolicy); var expression = value is ExpressionValue valueExp1 ? valueExp1.Expression : Expression.Constant(value, expressionValue.Property.PropertyType); if (value is ExpressionValue valueExp2 && valueExp2.Property.PropertyType != expressionValue.Property.PropertyType) { throw new ComparisonInvalidMatchTypeException(context); } if (expressionValue.Property.PropertyType != typeof(string) || value is ExpressionValue) { return(Expression.Lambda <Func <T, bool> >(Expression.Equal( expressionValue.Expression, expression ), parameter)); } var v = ((string)value).Replace(@"\*", MaskLk); if (v.IndexOf('*') != -1) { return(GetLkExpression <T>(parameter, context, jsonNamingPolicy)); } value = v.Replace(MaskLk, "*"); return(Expression.Lambda <Func <T, bool> >(Expression.Equal( expressionValue.Expression, Expression.Constant(value, expressionValue.Property.PropertyType)), parameter)); }
/// <summary> /// create like expression /// </summary> /// <returns></returns> private static Expression <Func <T, bool> > GetLkExpression <T>(ParameterExpression parameter, RSqlQueryParser.ComparisonContext context, JsonNamingPolicy jsonNamingPolicy = null) { var expressionValue = GetSelector <T>(parameter, context, jsonNamingPolicy); var values = RSqlQueryGetValueHelper.GetValues(expressionValue.Property.PropertyType, context.arguments()); if (values.Count > 1) { throw new ComparisonTooManyArgumentException(context); } var criteria = Convert.ToString(values[0]) ?? string.Empty; var maskStar = "{" + Guid.NewGuid() + "}"; criteria = criteria.Replace(@"\*", maskStar); MethodInfo method; if (!criteria.Contains('*')) { criteria += '*'; } if (criteria.StartsWith("*", StringComparison.Ordinal) && criteria.EndsWith("*", StringComparison.Ordinal)) { method = QueryReflectionHelper.MethodStringContains; } else if (criteria.StartsWith("*", StringComparison.Ordinal)) { method = QueryReflectionHelper.MethodStringEndsWith; } else { method = QueryReflectionHelper.MethodStringStartsWith; } criteria = criteria.Replace("*", "").Replace(maskStar, "*"); return(Expression.Lambda <Func <T, bool> >(Expression.Call(expressionValue.Expression, method, Expression.Constant(criteria, expressionValue.Property.PropertyType)), parameter)); }
/// <summary> /// create is null expression ( operator "=is-null=" or "=nil=" ) /// </summary> /// <param name="parameter"></param> /// <param name="context"></param> /// <param name="jsonNamingPolicy"></param> /// <typeparam name="T"></typeparam> /// <returns></returns> public static Expression <Func <T, bool> > GetIsNullExpression <T>(ParameterExpression parameter, RSqlQueryParser.ComparisonContext context, JsonNamingPolicy jsonNamingPolicy = null) { var expressionValue = GetSelector <T>(parameter, context, jsonNamingPolicy); if (!RSqlQueryGetValueHelper.IsNullableComparisonType(expressionValue.Property.PropertyType)) { throw new ComparisonInvalidComparatorSelectionException(context); } var values = RSqlQueryGetValueHelper.GetValues(typeof(bool), context.arguments()); if (!values.Any()) { throw new ComparisonNotEnoughArgumentException(context); } if (values.Count > 1) { throw new ComparisonTooManyArgumentException(context); } var result = Expression.Lambda <Func <T, bool> >(Expression.Equal( expressionValue.Expression, Expression.Constant(null, typeof(object))), parameter); if ((bool)values[0]) { return(result); } var body = Expression.Not(result.Body); result = Expression.Lambda <Func <T, bool> >(body, parameter); return(result); }
/// <summary> /// extract the multi value /// </summary> /// <param name="expressionValue"></param> /// <param name="context"></param> /// <returns></returns> /// <exception cref="ComparisonNotEnoughArgumentException"></exception> private static List <object> GetMultipleValue(ExpressionValue expressionValue, RSqlQueryParser.ComparisonContext context) { return(RSqlQueryGetValueHelper.GetValues(expressionValue.Property.PropertyType, context.arguments())); }