public static tbool And(tbool pr1, tbool pr2) { return(Ex.AndAlso(pr1, pr2)); }
private static LinqExpression EvaluateChildren(AttributePath path, System.Linq.Expressions.ParameterExpression arg, Func <System.Linq.Expressions.ParameterExpression, LinqExpression> callback = null) { if (path == null) { throw new ArgumentNullException(nameof(path)); } if (arg == null) { throw new ArgumentNullException(nameof(arg)); } var subArg = LinqExpression.Parameter(typeof(RepresentationAttribute), GetSc()); var subChild = LinqExpression.Parameter(typeof(RepresentationAttribute), GetSc()); var childrenProperty = LinqExpression.Property(arg, "Children"); var argChildrenProperty = LinqExpression.Property(subArg, "Children"); var schemaAttributeProperty = LinqExpression.Property(arg, "SchemaAttribute"); var schemaTypeProperty = LinqExpression.Property(schemaAttributeProperty, "Type"); var schemaMultiValuedProperty = LinqExpression.Property(schemaAttributeProperty, "MultiValued"); var isMultiValued = LinqExpression.Equal(schemaMultiValuedProperty, LinqExpression.Constant(true)); // true var isNotMultiValued = LinqExpression.Equal(schemaMultiValuedProperty, LinqExpression.Constant(false)); var isTypeComplex = LinqExpression.Equal(schemaTypeProperty, LinqExpression.Constant(Common.Constants.SchemaAttributeTypes.Complex)); var isNotTypeComplex = LinqExpression.NotEqual(schemaTypeProperty, LinqExpression.Constant(Common.Constants.SchemaAttributeTypes.Complex)); var isComplexMultiValued = LinqExpression.AndAlso(isMultiValued, isTypeComplex); var isNotComplexMultiValued = LinqExpression.OrElse(isNotTypeComplex, isNotMultiValued); var itemCount = LinqExpression.Call(typeof(Enumerable), "Count", new[] { typeof(RepresentationAttribute) }, childrenProperty); var moreThanZero = LinqExpression.GreaterThan(itemCount, LinqExpression.Constant(0)); LinqExpression result = null; if (callback != null) { result = callback(subChild); } if (path.Next != null) { var subCond = path.Next.Evaluate(subChild); if (result != null) { result = LinqExpression.AndAlso(result, subCond); } else { result = subCond; } } // a => aaze = azeaze var callEqualValue = LinqExpression.Lambda <Func <RepresentationAttribute, bool> >(result, subChild); // c => c.value = <value> var anyComplexMultiValuedSubAnyExpr = LinqExpression.Call(typeof(Enumerable), _anyMethodName, new[] { typeof(RepresentationAttribute) }, argChildrenProperty, callEqualValue); var lambdaMultiValuedSubAnyExpr = LinqExpression.Lambda <Func <RepresentationAttribute, bool> >(anyComplexMultiValuedSubAnyExpr, subArg); var anyComplexMultiValuedAnyExpr = LinqExpression.Call(typeof(Enumerable), _anyMethodName, new[] { typeof(RepresentationAttribute) }, childrenProperty, lambdaMultiValuedSubAnyExpr); var anyNotComplexMultiValuedExpr = LinqExpression.Call(typeof(Enumerable), _anyMethodName, new[] { typeof(RepresentationAttribute) }, childrenProperty, callEqualValue); var firstNotComplexMultiValued = LinqExpression.AndAlso(isNotComplexMultiValued, moreThanZero); var notComplexMultiValued = LinqExpression.AndAlso(firstNotComplexMultiValued, anyNotComplexMultiValuedExpr); var firstComplexMultiValued = LinqExpression.AndAlso(isComplexMultiValued, moreThanZero); var complexMultiValued = LinqExpression.AndAlso(firstComplexMultiValued, anyComplexMultiValuedAnyExpr); return(LinqExpression.OrElse(complexMultiValued, notComplexMultiValued)); }
/// <summary> /// Creates a lambda expression, that checks a Document to satisfy the list of conditions. /// Then compiles it and returns a predicate. /// </summary> private Func <Document, bool> CreatePredicate(Type entityType) { // parameter, that represents input Document var docParameter = Expression.Parameter(typeof(Document)); Expression predicateExp = null; foreach (var condition in this.Flatten()) { string fieldName = condition.Item1; var fieldPropertyInfo = entityType.GetProperty(fieldName); if (fieldPropertyInfo == null) { throw new InvalidOperationException(string.Format("An entity type {0} doesn't contain a property with name {1}, which was specified in search condition", entityType.Name, fieldName)); } var fieldType = fieldPropertyInfo.PropertyType; var fieldValues = condition.Item2.Values; // operation of getting a Document property value by it's name Expression getFieldExp = Expression.Property(docParameter, "Item", Expression.Constant(fieldName)); if (fieldType.BaseType == typeof(Enum)) { // need to convert enums to ints getFieldExp = Expression.Convert(getFieldExp, typeof(int)); } // operation of converting the property to fieldType var operand1 = Expression.Convert(getFieldExp, fieldType); Expression conditionExp; if (condition.Item2.Operator == ScanOperator.In) { // special support for IN operator var valueList = new ArrayList(); foreach (var fieldValue in fieldValues) { valueList.Add(fieldValue.ToObject(fieldType)); } conditionExp = Expression.Call ( Expression.Constant(valueList), "Contains", new Type[0], Expression.Convert(operand1, typeof(object)) ); } else { Expression valueExp = Expression.Constant(fieldValues[0]); if (fieldType.BaseType == typeof(Enum)) { // need to convert enums to ints valueExp = Expression.Convert(valueExp, typeof(int)); } // operation of converting the fieldValue to fieldType var operand2 = Expression.Convert(valueExp, fieldType); // now getting a predicate for current field conditionExp = ScanOperatorToExpression(condition.Item2.Operator, operand1, operand2); } // attaching it to other predicates predicateExp = predicateExp == null ? conditionExp : Expression.AndAlso(predicateExp, conditionExp); } Debug.Assert(predicateExp != null); // compiling the lambda into a predicate return((Func <Document, bool>)Expression.Lambda(predicateExp, docParameter).Compile()); }