/// <summary> /// create in expression ( operator "=in=" ) /// </summary> /// <returns></returns> public static Expression <Func <T, bool> > GetInExpression <T>(ParameterExpression parameter, QueryParser.ComparisonContext context, NamingStrategy namingStrategy = null) { if (parameter == null) { throw new ArgumentException(nameof(parameter)); } if (context == null) { throw new ArgumentException(nameof(context)); } var expressionValue = ExpressionValue.Parse <T>(parameter, context.selector().GetText(), namingStrategy); if (!EqOrNeqOrInOrOutAutorizedType.Contains(expressionValue.Property.PropertyType)) { throw new QueryComparisonInvalidComparatorSelectionException(context); } var values = QueryGetValueHelper.GetValues(expressionValue.Property.PropertyType, context.arguments()); if (values == null || values.Count == 0) { throw new QueryComparisonNotEnoughtArgumentException(context); } var methodContainsInfo = QueryReflectionHelper.GetOrRegistryContainsMethodInfo(expressionValue.Property.PropertyType); return(Expression.Lambda <Func <T, bool> >( Expression.Call(Expression.Constant(methodContainsInfo.Convert(values)), methodContainsInfo.ContainsMethod, expressionValue.Expression), parameter)); }
/// <summary> /// create greater than or equal expression ( operator ">=" or "=ge=" ) /// </summary> /// <param name="parameter"></param> /// <param name="context"></param> /// <param name="namingStrategy"></param> /// <typeparam name="T"></typeparam> /// <returns></returns> public static Expression <Func <T, bool> > GetGeExpression <T>(ParameterExpression parameter, QueryParser.ComparisonContext context, NamingStrategy namingStrategy = null) { if (parameter == null) { throw new ArgumentException(nameof(parameter)); } if (context == null) { throw new ArgumentException(nameof(context)); } var expressionValue = ExpressionValue.Parse <T>(parameter, context.selector().GetText(), namingStrategy); if (!LtOrGtOrLeOrLeAutorizedType.Contains(expressionValue.Property.PropertyType)) { throw new QueryComparisonInvalidComparatorSelectionException(context); } var value = GetUniqueValue <T>(parameter, expressionValue, context, namingStrategy); 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 QueryComparisonInvalidMatchTypeException(context); } return(Expression.Lambda <Func <T, bool> >(Expression.GreaterThanOrEqual( expressionValue.Expression, expression), parameter)); }
/// <summary> /// create like expression /// </summary> /// <returns></returns> private static Expression <Func <T, bool> > GetLkExpression <T>(ParameterExpression parameter, QueryParser.ComparisonContext context, NamingStrategy namingStrategy = null) { var expressionValue = ExpressionValue.Parse <T>(parameter, context.selector().GetText(), namingStrategy); if (expressionValue.Property.PropertyType != typeof(string)) { throw new QueryComparisonInvalidComparatorSelectionException(context); } var values = QueryGetValueHelper.GetValues(expressionValue.Property.PropertyType, context.arguments()); if (values == null || values.Count == 0) { throw new QueryComparisonNotEnoughtArgumentException(context); } if (values.Count > 1) { throw new QueryComparisonTooManyArgumentException(context); } var criteria = Convert.ToString(values[0]); var maskStar = "{" + Guid.NewGuid().ToString() + "}"; criteria = criteria.Replace(@"\*", maskStar); MethodInfo method; if (criteria.IndexOf('*') == -1) { criteria = criteria + '*'; } if (criteria.StartsWith("*") && criteria.EndsWith("*")) { method = QueryReflectionHelper.MethodStringContains; } else if (criteria.StartsWith("*")) { 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 equal expression ( operator "==" or "=eq=" ) /// </summary> /// <param name="parameter"></param> /// <param name="context"></param> /// <param name="namingStrategy"></param> /// <typeparam name="T"></typeparam> /// <returns></returns> public static Expression <Func <T, bool> > GetEqExpression <T>(ParameterExpression parameter, QueryParser.ComparisonContext context, NamingStrategy namingStrategy = null) { if (parameter == null) { throw new ArgumentException(nameof(parameter)); } if (context == null) { throw new ArgumentException(nameof(context)); } var expressionValue = ExpressionValue.Parse <T>(parameter, context.selector().GetText(), namingStrategy); if (!EqOrNeqOrInOrOutAutorizedType.Contains(expressionValue.Property.PropertyType)) { throw new QueryComparisonInvalidComparatorSelectionException(context); } var value = GetUniqueValue <T>(parameter, expressionValue, context, namingStrategy); 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 QueryComparisonInvalidMatchTypeException(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, namingStrategy)); } value = v.Replace(MaskLk, "*"); return(Expression.Lambda <Func <T, bool> >(Expression.Equal( expressionValue.Expression, Expression.Constant(value, 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="namingStrategy"></param> /// <typeparam name="T"></typeparam> /// <returns></returns> public static Expression <Func <T, bool> > GetIsNullExpression <T>(ParameterExpression parameter, QueryParser.ComparisonContext context, NamingStrategy namingStrategy = null) { if (parameter == null) { throw new ArgumentException(nameof(parameter)); } if (context == null) { throw new ArgumentException(nameof(context)); } var expressionValue = ExpressionValue.Parse <T>(parameter, context.selector().GetText(), namingStrategy); if (expressionValue.Property.PropertyType.IsValueType && !(expressionValue.Property.PropertyType.IsGenericType && expressionValue.Property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable <>))) { throw new QueryComparisonInvalidComparatorSelectionException(context); } var values = QueryGetValueHelper.GetValues(typeof(bool), context.arguments()); if (values == null || values.Count == 0) { throw new QueryComparisonNotEnoughtArgumentException(context); } if (values.Count > 1) { throw new QueryComparisonTooManyArgumentException(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); }