/// <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)); }
public void ExitComparison(QueryParser.ComparisonContext context) { var opToken = context.REL_OP(); if (opToken == null) { return; } var op = opToken.Symbol; var right = _expressions.Pop(); var left = _expressions.Pop(); BinaryOperatorExpression value = null; switch (op.Text) { case "<": value = new LessThanOperator(op.Line, op.Column, left, right); break; case "<=": value = new LessThanOrEqualOperator(op.Line, op.Column, left, right); break; case "<>": case "!=": value = new NotEqualOperator(op.Line, op.Column, left, right); break; case "==": case "=": value = new EqualOperator(op.Line, op.Column, left, right); break; case ">": value = new GreaterThanOperator(op.Line, op.Column, left, right); break; case ">=": value = new GreaterThanOrEqualOperator(op.Line, op.Column, left, right); break; } Trace.Assert(value != null, "Invalid comparison operator " + op.Text); _expressions.Push(value); }
/// <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 not in expression ( operator "=out=" or "=nin=" ) /// </summary> /// <returns></returns> public static Expression <Func <T, bool> > GetOutExpression <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 expression = GetInExpression <T>(parameter, context, namingStrategy); var body = Expression.Not(expression.Body); return(Expression.Lambda <Func <T, bool> >(body, parameter)); }
/// <summary> /// visit a comparison expression /// </summary> /// <param name="context"></param> /// <returns></returns> public override Expression <Func <T, bool> > VisitComparison(QueryParser.ComparisonContext context) { var comparator = context.comparator().GetText().ToLowerInvariant(); switch (comparator) { case "=is-null=": case "=nil=": return(QueryExpressionHelper.GetIsNullExpression <T>(_parameter, context, _namingStrategy)); case "==": case "=eq=": return(QueryExpressionHelper.GetEqExpression <T>(_parameter, context, _namingStrategy)); case "!=": case "=neq=": return(QueryExpressionHelper.GetNeqExpression <T>(_parameter, context, _namingStrategy)); case "<": case "=lt=": return(QueryExpressionHelper.GetLtExpression <T>(_parameter, context, _namingStrategy)); case "<=": case "=le=": return(QueryExpressionHelper.GetLeExpression <T>(_parameter, context, _namingStrategy)); case ">": case "=gt=": return(QueryExpressionHelper.GetGtExpression <T>(_parameter, context, _namingStrategy)); case ">=": case "=ge=": return(QueryExpressionHelper.GetGeExpression <T>(_parameter, context, _namingStrategy)); case "=in=": return(QueryExpressionHelper.GetInExpression <T>(_parameter, context, _namingStrategy)); case "=out=": case "=nin=": return(QueryExpressionHelper.GetOutExpression <T>(_parameter, context, _namingStrategy)); default: throw new QueryComparisonUnknownComparatorException(context); } }
/// <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); }
private static object GetUniqueValue <T>(ParameterExpression parameter, ExpressionValue expressionValue, QueryParser.ComparisonContext context, NamingStrategy namingStrategy = null) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var value = context.arguments().value(); if (value.Length == 0) { throw new QueryComparisonNotEnoughtArgumentException(context); } if (value.Length > 1) { throw new QueryComparisonNotEnoughtArgumentException(context); } return(QueryGetValueHelper.GetValue <T>(parameter, expressionValue, context, namingStrategy)); }
public QueryComparisonUnknownSelectorException(QueryParser.ComparisonContext origin, Exception innerException = null) : base(origin, string.Format("Unknown selector : '{0}'", origin.selector().GetText()), innerException) { }
public QueryComparisonInvalidMatchTypeException(QueryParser.ComparisonContext origin, Exception innerException = null) : base(origin, string.Format("Invalid comparison match type : {0} and {1}", origin.selector().GetText(), origin.arguments().GetText()), innerException) { }
public QueryComparisonTooManyArgumentException(QueryParser.ComparisonContext origin, Exception innerException = null) : base(origin, string.Format("Too many arguments : {0}", origin.selector().GetText()), innerException) { }
public QueryComparisonUnknownComparatorException(QueryParser.ComparisonContext origin, Exception innerException = null) : base(origin, string.Format("Unknown comparator : {0}", origin.comparator().GetText()), innerException) { }
public static object GetValue <T>(ParameterExpression parameter, ExpressionValue expressionValue, QueryParser.ComparisonContext context, NamingStrategy namingStrategy = null) { if (parameter == null) { throw new ArgumentNullException(nameof(parameter)); } if (expressionValue == null) { throw new ArgumentNullException(nameof(expressionValue)); } if (context == null) { throw new ArgumentNullException(nameof(context)); } if (expressionValue.Property.PropertyType == typeof(string)) { return(GetString <T>(parameter, context.arguments().value()[0], namingStrategy)); } if (expressionValue.Property.PropertyType == typeof(short) || expressionValue.Property.PropertyType == typeof(short?)) { return(GetShort <T>(parameter, context.arguments().value()[0], namingStrategy)); } if (expressionValue.Property.PropertyType == typeof(int) || expressionValue.Property.PropertyType == typeof(int?)) { return(GetInt <T>(parameter, context.arguments().value()[0], namingStrategy)); } if (expressionValue.Property.PropertyType == typeof(long) || expressionValue.Property.PropertyType == typeof(long?)) { return(GetLong <T>(parameter, context.arguments().value()[0], namingStrategy)); } if (expressionValue.Property.PropertyType == typeof(float) || expressionValue.Property.PropertyType == typeof(float?)) { return(GetFloat <T>(parameter, context.arguments().value()[0], namingStrategy)); } if (expressionValue.Property.PropertyType == typeof(double) || expressionValue.Property.PropertyType == typeof(double?)) { return(GetDouble <T>(parameter, context.arguments().value()[0], namingStrategy)); } if (expressionValue.Property.PropertyType == typeof(decimal) || expressionValue.Property.PropertyType == typeof(decimal?)) { return(GetDecimal <T>(parameter, context.arguments().value()[0], namingStrategy)); } if (expressionValue.Property.PropertyType == typeof(bool) || expressionValue.Property.PropertyType == typeof(bool?)) { return(GetBoolean <T>(parameter, context.arguments().value()[0], namingStrategy)); } if (expressionValue.Property.PropertyType == typeof(DateTime) || expressionValue.Property.PropertyType == typeof(DateTime?)) { return(GetDateTime <T>(parameter, context.arguments().value()[0], namingStrategy)); } if (expressionValue.Property.PropertyType == typeof(DateTimeOffset) || expressionValue.Property.PropertyType == typeof(DateTimeOffset?)) { return(GetDateTimeOffset <T>(parameter, context.arguments().value()[0], namingStrategy)); } return(null); }
/// <summary> /// Visit a parse tree produced by <see cref="QueryParser.comparison"/>. /// <para> /// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/> /// on <paramref name="context"/>. /// </para> /// </summary> /// <param name="context">The parse tree.</param> /// <return>The visitor result.</return> public virtual Result VisitComparison([NotNull] QueryParser.ComparisonContext context) { return(VisitChildren(context)); }
public void EnterComparison(QueryParser.ComparisonContext context) { }
/// <summary> /// Exit a parse tree produced by <see cref="QueryParser.comparison"/>. /// <para>The default implementation does nothing.</para> /// </summary> /// <param name="context">The parse tree.</param> public virtual void ExitComparison([NotNull] QueryParser.ComparisonContext context) { }
public QueryComparisonInvalidComparatorSelectionException(QueryParser.ComparisonContext origin, Exception innerException = null) : base(origin, string.Format("Invalid selector : {0}", origin.selector().GetText()), innerException) { }
public QueryComparisonNotEnoughtArgumentException(QueryParser.ComparisonContext origin, Exception innerException = null) : base(origin, string.Format("Not enought argument : {0}", origin.selector().GetText()), innerException) { }