/// <summary> /// Builds the <see cref="CriteriaExpression"/>, and returns an <see cref="Expression"/>. /// </summary> /// <typeparam name="T">Type used in the <see cref="Expression{TDelegate}"/>.</typeparam> /// <param name="criteriaExpression">The <see cref="CriteriaExpression"/>.</param> /// <returns>The <see cref="Expression{T}"/></returns> public virtual Expression <Func <T, bool> > Build <T>(CriteriaExpression criteriaExpression) where T : class { if (criteriaExpression == null) { throw new ArgumentNullException(nameof(criteriaExpression)); } var parameter = Expression.Parameter(typeof(T), "x"); var expression = this.BuildExpression(criteriaExpression, parameter); return(Expression.Lambda <Func <T, bool> >(expression ?? Expression.Constant(true), parameter)); }
/// <summary> /// Builds the <see cref="CriteriaExpression"/>'s, and returns an <see cref="Expression"/>. /// </summary> /// <typeparam name="T">Type used in the <see cref="Expression{TDelegate}"/>.</typeparam> /// <param name="criteriaExpression">The <see cref="CriteriaExpression"/>.</param> /// <returns>The <see cref="Expression{T}"/></returns> public virtual Expression <Func <T, bool> > Build <T>(CriteriaExpression criteriaExpression) where T : class { if (criteriaExpression == null) { throw new ArgumentNullException(nameof(criteriaExpression)); } var logicalType = LogicalType.And; var parameter = Expression.Parameter(typeof(T), "x"); Expression expression = null; foreach (var statement in criteriaExpression.Criterias) { Expression innerExpression; if (statement.Property.Contains("[") && statement.Property.Contains("]")) { var baseName = statement.Property.Substring(0, statement.Property.IndexOf("[", StringComparison.Ordinal)); var name = statement.Property.Replace(baseName, "").Replace("[", "").Replace("]", ""); var type = parameter.Type.GetRuntimeProperty(baseName).PropertyType.GenericTypeArguments[0]; var method = typeof(Enumerable).GetRuntimeMethods().First(m => m.Name == "Any" && m.GetParameters().Length == 2).MakeGenericMethod(type); var member = this.GetMember(parameter, baseName); var parameter2 = Expression.Parameter(type, "i"); var expr2 = Expression.Lambda(this.GetExpression(parameter2, statement, name), parameter2); innerExpression = Expression.Call(method, member, expr2); } else { innerExpression = this.GetExpression(parameter, statement); } expression = expression == null ? innerExpression : logicalType == LogicalType.And ? Expression.AndAlso(expression, innerExpression) : Expression.OrElse(expression, innerExpression); logicalType = statement.LogicalType; } return(Expression.Lambda <Func <T, bool> >(expression ?? Expression.Constant(true), parameter)); }
private Expression BuildExpression(CriteriaExpression criteriaExpression, Expression parameter) { var prevLogicalType = LogicalType.And; Expression expression = null; foreach (var criteria in criteriaExpression.Criterias) { Expression innerExpression; if (criteria.Property.Contains("[") && criteria.Property.Contains("]")) { var baseName = criteria.Property.Substring(0, criteria.Property.IndexOf("[", StringComparison.Ordinal)); var name = criteria.Property.Replace(baseName, "").Replace("[", "").Replace("]", ""); var type = parameter.Type.GetRuntimeProperty(baseName).PropertyType.GenericTypeArguments[0]; var method = typeof(Enumerable).GetRuntimeMethods().First(x => x.Name == "Any" && x.GetParameters().Length == 2).MakeGenericMethod(type); var member = this.GetMember(parameter, baseName); var parameter2 = Expression.Parameter(type, "i"); var expr2 = Expression.Lambda(this.GetExpression(parameter2, criteria, name), parameter2); innerExpression = Expression.Call(method, member, expr2); } else { innerExpression = this.GetExpression(parameter, criteria); } expression = expression == null ? innerExpression : prevLogicalType == LogicalType.And ? Expression.AndAlso(expression, innerExpression) : Expression.OrElse(expression, innerExpression); prevLogicalType = criteria.LogicalType; } return(expression); }