/// <summary> /// Get LINQ string from filter expression (IQuaryable) /// </summary> /// <param name="filterElement">Filter expression</param> /// <param name="classType">Object Type for filtering (it contain filtering fields)</param> /// <param name="knownTypes">Known Types if use polymorphism</param> /// <param name="preambule">Preambule for LINQ string</param> /// <returns>Filter expression for LINQ</returns> public static string GetLinqFilteringConditions(ExpressionTreeElement filterElement, Type classType, Dictionary <Type, Type[]> knownTypes = null, string preambule = null) { var fieldLeaf = filterElement as ExpressionTreeFieldLeaf; if (fieldLeaf != null) { bool isFindProperty; var filterProp = ReflectionHelper.GetPropertyPathFromClass(fieldLeaf.PropertyDescription.FieldName, classType, knownTypes, preambule, out isFindProperty); if (isFindProperty) { if (fieldLeaf.Property.PropertyType == typeof(string)) { return(filterProp); } if (fieldLeaf.Property.PropertyType == typeof(DateTime)) { filterProp += ".Ticks"; } else if (fieldLeaf.Property.PropertyType.IsClass && fieldLeaf.Property.PropertyType != typeof(Enum)) { filterProp += ".HashCode"; } else if (fieldLeaf.PropertyDescription.NumberStyle == NumberStyles.HexNumber) { filterProp = "(Int64(" + filterProp + ")).ToString(\"X\")"; } return(filterProp); } } var valueLeaf = filterElement as ExpressionTreeValueLeaf; if (valueLeaf != null) { var fieldByValueLeaf = valueLeaf.Parent.Left as ExpressionTreeFieldLeaf; if (fieldByValueLeaf != null) { var fieldType = ReflectionHelper.GetRealType(fieldByValueLeaf.Property.PropertyType); if (fieldType == typeof(string) || fieldType == typeof(Enum) || fieldType.BaseType == typeof(Enum)) { return("\"" + valueLeaf.FieldValue + "\""); } if (fieldType == typeof(DateTime)) { return(((DateTime)valueLeaf.FieldValue).Ticks.ToString()); } if (fieldType.IsClass) { return(valueLeaf.FieldValue.GetType() .GetProperty("HashCode") .GetValue(valueLeaf.FieldValue) .ToString()); } if (fieldByValueLeaf.PropertyDescription.NumberStyle == NumberStyles.HexNumber) { long value; if (long.TryParse(valueLeaf.ToString(), out value)) { return(value.ToString("X")); } } } return(valueLeaf.FieldValue.ToString()); } var comparisonNode = filterElement as ComparisonOperatorNode; if (comparisonNode != null) { var comparisonNodeValueLeaf = comparisonNode.Right as ExpressionTreeValueLeaf; if (comparisonNodeValueLeaf != null) { var comparisonNodeFieldLeaf = comparisonNode.Left as ExpressionTreeFieldLeaf; string expressionFieldProp; bool isFindProperty = false; if (comparisonNodeFieldLeaf != null && ReflectionHelper.IsNullable(comparisonNodeFieldLeaf.Property.PropertyType)) { expressionFieldProp = ReflectionHelper.GetPropertyPathFromClass(comparisonNodeFieldLeaf.PropertyDescription.FieldName, classType, knownTypes, preambule, out isFindProperty); } else { expressionFieldProp = GetLinqFilteringConditions(comparisonNodeFieldLeaf, classType, knownTypes, preambule); } if (comparisonNodeValueLeaf.FieldValue == null || (comparisonNodeValueLeaf.FieldValue is String && String.IsNullOrWhiteSpace(comparisonNodeValueLeaf.FieldValue as String))) { return(expressionFieldProp + ComparisonFilterOperatorToLinq(comparisonNode.Operator, false, true) + "null"); } var valueStr = GetLinqFilteringConditions(comparisonNode.Right, classType, knownTypes, preambule); if (comparisonNode.Operator == ComparisonOperators.StartsWith) { valueStr = "(\"" + valueStr + "\")"; } var preExpression = String.Empty; if (comparisonNodeFieldLeaf != null && ReflectionHelper.IsNullable(comparisonNodeFieldLeaf.Property.PropertyType) && isFindProperty) { preExpression = expressionFieldProp + ComparisonFilterOperatorToLinq(ComparisonOperators.NotEqual, false, true) + "null" + BooleanFilterOperatorToLinq(BooleanOperators.And); } return(preExpression + GetLinqFilteringConditions(comparisonNodeFieldLeaf, classType, knownTypes, preambule) + ComparisonFilterOperatorToLinq(comparisonNode.Operator, comparisonNodeValueLeaf.FieldValue is Enum) + valueStr); } } var booleanNode = filterElement as BooleanOperatorNode; if (booleanNode != null) { return(GetLinqFilteringConditions(booleanNode.Left, classType, knownTypes, preambule) + BooleanFilterOperatorToLinq(booleanNode.Operator) + GetLinqFilteringConditions(booleanNode.Right, classType, knownTypes, preambule)); } return(String.Empty); }
/// <summary> /// Получить строковое выражение фильтрации /// </summary> /// <param name="filterElement">Параметры фильтра</param> /// <param name="filterablePropertyDescription">Описание свойств фильтрации</param> /// <returns>Строковое выражение фильтрации</returns> private string GetStringFilteringConditions(ExpressionTreeElement filterElement, FilterablePropertyDescriptionCollection filterablePropertyDescription) { var fieldLeaf = filterElement as ExpressionTreeFieldLeaf; if (fieldLeaf != null) { var foundFieldDescr = filterablePropertyDescription.FirstOrDefault( prop => prop.BoundProperty.Equals(fieldLeaf.PropertyDescription)); if (foundFieldDescr != null) { return(foundFieldDescr.Title); } } var valueLeaf = filterElement as ExpressionTreeValueLeaf; if (valueLeaf != null) { var fieldForValue = filterElement.Parent.Left as ExpressionTreeFieldLeaf; if (fieldForValue != null) { var foundFieldDescr = filterablePropertyDescription.FirstOrDefault( prop => prop.BoundProperty.Equals(fieldForValue.PropertyDescription)); if (foundFieldDescr != null && foundFieldDescr.ValueToStringConverter != null) { return(foundFieldDescr.ValueToStringConverter.Convert(valueLeaf.FieldValue, valueLeaf.FieldValue.GetType(), null, CultureInfo.CurrentCulture).ToString()); } } if (valueLeaf.FieldValue is string) { return("\"" + valueLeaf.FieldValue + "\""); } if (valueLeaf.FieldValue is DateTime) { return("\"" + ((DateTime)valueLeaf.FieldValue).ToString(CultureInfo.CurrentCulture) + "\""); } if (valueLeaf.FieldValue == null) { return(LocalizationDictionary.Empty); } else { return(valueLeaf.FieldValue.ToString()); } } var comparisonNode = filterElement as ComparisonOperatorNode; if (comparisonNode != null) { if (comparisonNode.Right is ExpressionTreeValueLeaf) { if (((ExpressionTreeValueLeaf)comparisonNode.Right).FieldValue == null || (((ExpressionTreeValueLeaf)comparisonNode.Right).FieldValue is String && String.IsNullOrEmpty(((ExpressionTreeValueLeaf)comparisonNode.Right).FieldValue as String))) { return(GetStringFilteringConditions(comparisonNode.Left, filterablePropertyDescription) + " " + ComparisonOperatorNode.OperatorToString(comparisonNode.Operator) + " " + LocalizationDictionary.Empty); } return(GetStringFilteringConditions(comparisonNode.Left, filterablePropertyDescription) + " " + ComparisonOperatorNode.OperatorToString(comparisonNode.Operator) + " " + GetStringFilteringConditions(comparisonNode.Right, filterablePropertyDescription)); } } var booleanNode = filterElement as BooleanOperatorNode; if (booleanNode != null) { var boolOperatorItemsSource = new LocalizableEnumItemsSource { Type = typeof(BooleanOperators) }; if (booleanNode.Operator == BooleanOperators.Not) { return(boolOperatorItemsSource.Convert(booleanNode.Operator, null, null, null) + " " + (booleanNode.Left is BooleanOperatorNode ? "( " : String.Empty) + GetStringFilteringConditions(booleanNode.Left, filterablePropertyDescription) + (booleanNode.Left is BooleanOperatorNode ? " )" : String.Empty)); } return(GetStringFilteringConditions(booleanNode.Left, filterablePropertyDescription) + " " + boolOperatorItemsSource.Convert(booleanNode.Operator, null, null, null) + " " + GetStringFilteringConditions(booleanNode.Right, filterablePropertyDescription)); } return(String.Empty); }