public Criteria <TEntity> Or(string selectorString, Operator operationType, object value) { if (string.IsNullOrWhiteSpace(selectorString)) { throw new ArgumentException("Selector string can not be null or empty", "selectorString"); } var targetPropertyType = GetTargetPropertyType(entityType, selectorString); if (targetPropertyType != value.GetType() && operationType != Operator.Contain && operationType != Operator.NotContain) { value = ChangeValueType(targetPropertyType, value); } var conditionTree = new ConditionTree() { OperationType = operationType, Value = value, NextLogicalOperator = LogicalOperator.Or, SelectorString = selectorString }; var newConditionTree = conditionTree; newConditionTree.Id = idGenerator.GetId(newConditionTree, out firstTime); ConditionContainer.Tree.Children.Add(newConditionTree); return(this); }
private static ConditionTree CopyConditionTree(ConditionTree sourceConditionTree) { if (sourceConditionTree == null) { return(null); } var conditionTree = new ConditionTree() { Id = sourceConditionTree.Id, NextLogicalOperator = sourceConditionTree.NextLogicalOperator, OperationType = sourceConditionTree.OperationType, SelectorString = sourceConditionTree.SelectorString, Value = sourceConditionTree.Value, SerializedValue = sourceConditionTree.SerializedValue }; var result = conditionTree; if (sourceConditionTree.Children != null && sourceConditionTree.Children.Count > 0) { result.Children = new List <ConditionTree>(); foreach (var childrenCondition in sourceConditionTree.Children) { var clonedObject = CopyConditionTree(childrenCondition); if (clonedObject == null) { continue; } result.Children.Add(clonedObject); } } return(result); }
public Criteria <TEntity> Or <TProperty>(Expression <Func <TEntity, TProperty> > selectorExpression, Operator operationType, object value) { if (selectorExpression == null) { throw new ArgumentException("Selector string can not be null or empty", "selectorExpression"); } var conditionTree = new ConditionTree() { OperationType = operationType, Value = value, NextLogicalOperator = LogicalOperator.Or, SelectorString = GetSelectorStringFromExpression(selectorExpression) }; var newConditionTree = conditionTree; newConditionTree.Id = idGenerator.GetId(newConditionTree, out firstTime); ConditionContainer.Tree.Children.Add(newConditionTree); return(this); }
public static Criteria <TEntity> True() { var entityType = typeof(TEntity); var criterium = new Criteria <TEntity>(); var condition = new Condition(); var conditionTree = new ConditionTree() { OperationType = Operator.None, NextLogicalOperator = LogicalOperator.And, Value = TrueFalse.True }; condition.Tree = conditionTree; condition.EntityTypeName = entityType.Name; criterium.ConditionContainer = condition; criterium.entityType = entityType; var critaria = criterium; critaria.ConditionContainer.Id = idGenerator.GetId(critaria.ConditionContainer, out firstTime); critaria.ConditionContainer.Tree.Id = idGenerator.GetId(critaria.ConditionContainer.Tree, out firstTime); return(critaria); }
private Expression ConvertConditionToExpresion(ConditionTree conditionTree, Type parameterExpressionType, ParameterExpression parameterExpression) { var resultExpression = GetConditionExpression(conditionTree, parameterExpressionType, parameterExpression); foreach (var childrenConditionTree in conditionTree.Children) { if (checkedIds.Contains(childrenConditionTree.Id)) { continue; } checkedIds.Add(childrenConditionTree.Id); switch (conditionTree.NextLogicalOperator) { case LogicalOperator.And: { resultExpression = Expression.AndAlso(resultExpression, ConvertConditionToExpresion(childrenConditionTree, parameterExpressionType, parameterExpression)); continue; } case LogicalOperator.Or: { resultExpression = Expression.OrElse(resultExpression, ConvertConditionToExpresion(childrenConditionTree, parameterExpressionType, parameterExpression)); continue; } default: { continue; } } } return(resultExpression); }
private static Expression GetConditionExpression(ConditionTree conditionForConvert, Type parameterExpressionType, ParameterExpression parameterExpression) { Expression result; object valueObject; Expression[] expressionArray; string serializedValue; object str; string serializedValue1; string str1; string serializedValue2; string str2; string serializedValue3; string str3; if (conditionForConvert == null) { throw new ArgumentNullException("conditionForConvert", "Condition tree is null"); } if (conditionForConvert.OperationType == Operator.None && string.Equals(conditionForConvert.SerializedValue, 1.ToString(CultureInfo.InvariantCulture), StringComparison.InvariantCultureIgnoreCase)) { var constantExpression = Expression.Constant(1, typeof(int)); return(Expression.Equal(constantExpression, constantExpression)); } if (conditionForConvert.OperationType == Operator.None && string.Equals(conditionForConvert.SerializedValue, 2.ToString(CultureInfo.InvariantCulture), StringComparison.InvariantCultureIgnoreCase)) { var constantExpression = Expression.Constant(1, typeof(int)); return(Expression.NotEqual(constantExpression, constantExpression)); } ConstantExpression rightSide = null; Expression collection = null; var leftSidePropertyType = GetTargetPropertyType(parameterExpressionType, conditionForConvert.SelectorString); var isNumericType = leftSidePropertyType.IsNumericType(); var isString = leftSidePropertyType == stringType; MethodInfo trimMethodInfo = null; MethodInfo trimStartMethodInfo = null; MethodInfo trimEndMethodInfo = null; MethodInfo startsWithMethodInfo = null; MethodInfo endsWithMethodInfo = null; MethodInfo containsMethodInfo = null; MethodInfo stringCompareMethodInfo = null; Expression argumantsExpression = null; var leftSile = GetLeftSide(conditionForConvert.SelectorString, parameterExpressionType, parameterExpression); switch (conditionForConvert.OperationType) { case Operator.Contain: case Operator.NotContain: { if (!string.IsNullOrEmpty(conditionForConvert.SerializedValue)) { serializedValue = conditionForConvert.SerializedValue; } else { serializedValue = null; } if (leftSidePropertyType == stringType) { throw new InvalidOperationException("包含字符串的查询请使用 Like 系列操作符!"); } Type numbericGenericType = typeof(ICollection <>).MakeGenericType(leftSidePropertyType); valueObject = JsonConvert.DeserializeObject(serializedValue, numbericGenericType); var typeArray = new Type[] { leftSidePropertyType }; containsMethodInfo = numbericGenericType.GetMethod("Contains", typeArray); collection = Expression.Constant(valueObject); break; } case Operator.Like: case Operator.NotLike: { var type = typeof(string); var typeArray1 = new Type[] { typeof(string) }; containsMethodInfo = type.GetMethod("Contains", typeArray1); trimMethodInfo = typeof(string).GetMethod("Trim", new Type[0]); if (!string.IsNullOrEmpty(conditionForConvert.SerializedValue)) { serializedValue1 = conditionForConvert.SerializedValue; } else { serializedValue1 = null; } valueObject = JsonConvert.DeserializeObject(serializedValue1, leftSidePropertyType); rightSide = Expression.Constant(valueObject, leftSidePropertyType); break; } case Operator.StartsWith: case Operator.NotStartsWith: { var type1 = typeof(string); var typeArray2 = new Type[] { typeof(string) }; startsWithMethodInfo = type1.GetMethod("StartsWith", typeArray2); trimStartMethodInfo = typeof(string).GetMethod("TrimStart", BindingFlags.Instance | BindingFlags.Public); argumantsExpression = Expression.NewArrayInit(typeof(char), new Expression[0]); if (!string.IsNullOrEmpty(conditionForConvert.SerializedValue)) { str1 = conditionForConvert.SerializedValue; } else { str1 = null; } valueObject = JsonConvert.DeserializeObject(str1, leftSidePropertyType); rightSide = Expression.Constant(valueObject, leftSidePropertyType); break; } case Operator.EndsWith: case Operator.NotEndsWith: { var type2 = typeof(string); var typeArray3 = new Type[] { typeof(string) }; endsWithMethodInfo = type2.GetMethod("EndsWith", typeArray3); trimEndMethodInfo = typeof(string).GetMethod("TrimEnd", BindingFlags.Instance | BindingFlags.Public); argumantsExpression = Expression.NewArrayInit(typeof(char), new Expression[0]); if (!string.IsNullOrEmpty(conditionForConvert.SerializedValue)) { serializedValue2 = conditionForConvert.SerializedValue; } else { serializedValue2 = null; } valueObject = JsonConvert.DeserializeObject(serializedValue2, leftSidePropertyType); rightSide = Expression.Constant(valueObject, leftSidePropertyType); break; } case Operator.GreaterThan: case Operator.GreaterThanOrEqual: case Operator.LessThan: case Operator.LessThanOrEqual: { if (!isString) { if (!string.IsNullOrEmpty(conditionForConvert.SerializedValue)) { str2 = conditionForConvert.SerializedValue; } else { str2 = null; } valueObject = JsonConvert.DeserializeObject(str2, leftSidePropertyType); rightSide = Expression.Constant(valueObject, leftSidePropertyType); break; } else { var type3 = typeof(string); var typeArray4 = new Type[] { typeof(string) }; stringCompareMethodInfo = type3.GetMethod("CompareTo", typeArray4); if (!string.IsNullOrEmpty(conditionForConvert.SerializedValue)) { serializedValue3 = conditionForConvert.SerializedValue; } else { serializedValue3 = null; } valueObject = JsonConvert.DeserializeObject(serializedValue3, leftSidePropertyType); rightSide = Expression.Constant(valueObject, leftSidePropertyType); break; } } case Operator.IsNull: case Operator.IsNotNull: { rightSide = Expression.Constant(null); valueObject = null; break; } default: { if (!string.IsNullOrEmpty(conditionForConvert.SerializedValue)) { str3 = conditionForConvert.SerializedValue; } else { str3 = null; } valueObject = JsonConvert.DeserializeObject(str3, leftSidePropertyType); rightSide = Expression.Constant(valueObject, leftSidePropertyType); break; } } UnaryExpression unaryExpression = null; ConstantExpression convertedRightSideConstantExpression = null; var nullableDoubleType = typeof(double?); MethodInfo stringConvertMethodInfo = null; if (isNumericType) { //Type type4 = typeof(SqlFunctions); //Type[] typeArray5 = { nullableDoubleType }; //stringConvertMethodInfo = typeof(SqlFunctions).GetMethod("StringConvert", new[] { nullableDoubleType }); stringConvertMethodInfo = typeof(Criteria <>).GetMethod("StringConvert", new[] { nullableDoubleType }); unaryExpression = Expression.Convert(leftSile, nullableDoubleType); if (valueObject == null) { str = null; } else { str = valueObject.ToString(); } convertedRightSideConstantExpression = Expression.Constant(str); } switch (conditionForConvert.OperationType) { case Operator.Equal: case Operator.IsNull: { result = Expression.Equal(leftSile, rightSide); break; } case Operator.NotEqual: case Operator.IsNotNull: { result = Expression.NotEqual(leftSile, rightSide); break; } case Operator.Contain: { expressionArray = new Expression[] { leftSile }; result = Expression.Call(collection, containsMethodInfo, expressionArray); break; } case Operator.NotContain: { var expressionArray1 = new Expression[] { leftSile }; result = Expression.Not(Expression.Call(collection, containsMethodInfo, expressionArray1)); break; } case Operator.Like: { if (!isNumericType) { var expressionArray2 = new Expression[] { rightSide }; result = Expression.Call(leftSile, containsMethodInfo, expressionArray2); break; } else { var methodCallExpression1 = Expression.Call(stringConvertMethodInfo, unaryExpression); var methodCallExpression2 = Expression.Call(methodCallExpression1, trimMethodInfo); var expressionArray3 = new Expression[] { convertedRightSideConstantExpression }; result = Expression.Call(methodCallExpression2, containsMethodInfo, expressionArray3); break; } } case Operator.NotLike: { if (!isNumericType) { var expressionArray4 = new Expression[] { rightSide }; result = Expression.Not(Expression.Call(leftSile, containsMethodInfo, expressionArray4)); break; } else { var methodCallExpression1 = Expression.Call(stringConvertMethodInfo, unaryExpression); var methodCallExpression2 = Expression.Call(methodCallExpression1, trimMethodInfo); var expressionArray5 = new Expression[] { convertedRightSideConstantExpression }; result = Expression.Call(methodCallExpression2, containsMethodInfo, expressionArray5); result = Expression.Not(result); break; } } case Operator.StartsWith: { if (!isNumericType) { var expressionArray6 = new Expression[] { rightSide }; result = Expression.Call(leftSile, startsWithMethodInfo, expressionArray6); break; } else { var methodCallExpression1 = Expression.Call(stringConvertMethodInfo, unaryExpression); var expressionArray7 = new Expression[] { argumantsExpression }; var methodCallExpression2 = Expression.Call(methodCallExpression1, trimStartMethodInfo, expressionArray7); var expressionArray8 = new Expression[] { convertedRightSideConstantExpression }; result = Expression.Call(methodCallExpression2, startsWithMethodInfo, expressionArray8); break; } } case Operator.NotStartsWith: { if (!isNumericType) { var expressionArray9 = new Expression[] { rightSide }; result = Expression.Not(Expression.Call(leftSile, startsWithMethodInfo, expressionArray9)); break; } else { var methodCallExpression1 = Expression.Call(stringConvertMethodInfo, unaryExpression); var expressionArray10 = new Expression[] { argumantsExpression }; var methodCallExpression2 = Expression.Call(methodCallExpression1, trimStartMethodInfo, expressionArray10); var expressionArray11 = new Expression[] { convertedRightSideConstantExpression }; result = Expression.Call(methodCallExpression2, startsWithMethodInfo, expressionArray11); result = Expression.Not(result); break; } } case Operator.EndsWith: { if (!isNumericType) { expressionArray = new Expression[] { rightSide }; result = Expression.Call(leftSile, endsWithMethodInfo, expressionArray); break; } else { var methodCallExpression1 = Expression.Call(stringConvertMethodInfo, unaryExpression); expressionArray = new Expression[] { argumantsExpression }; var methodCallExpression2 = Expression.Call(methodCallExpression1, trimEndMethodInfo, expressionArray); expressionArray = new Expression[] { convertedRightSideConstantExpression }; result = Expression.Call(methodCallExpression2, endsWithMethodInfo, expressionArray); break; } } case Operator.NotEndsWith: { if (!isNumericType) { expressionArray = new Expression[] { rightSide }; result = Expression.Not(Expression.Call(leftSile, endsWithMethodInfo, expressionArray)); break; } else { var methodCallExpression1 = Expression.Call(stringConvertMethodInfo, unaryExpression); expressionArray = new Expression[] { argumantsExpression }; var methodCallExpression2 = Expression.Call(methodCallExpression1, trimEndMethodInfo, expressionArray); expressionArray = new Expression[] { convertedRightSideConstantExpression }; result = Expression.Call(methodCallExpression2, endsWithMethodInfo, expressionArray); result = Expression.Not(result); break; } } case Operator.GreaterThan: { if (!isString) { result = Expression.GreaterThan(leftSile, rightSide); break; } else { expressionArray = new Expression[] { rightSide }; result = Expression.GreaterThan(Expression.Call(leftSile, stringCompareMethodInfo, expressionArray), Expression.Constant(0)); break; } } case Operator.GreaterThanOrEqual: { if (!isString) { result = Expression.GreaterThanOrEqual(leftSile, rightSide); break; } else { expressionArray = new Expression[] { rightSide }; result = Expression.GreaterThanOrEqual( Expression.Call(leftSile, stringCompareMethodInfo, expressionArray), Expression.Constant(0)); break; } } case Operator.LessThan: { if (!isString) { result = Expression.LessThan(leftSile, rightSide); break; } else { expressionArray = new Expression[] { rightSide }; result = Expression.LessThan( Expression.Call(leftSile, stringCompareMethodInfo, expressionArray), Expression.Constant(0)); break; } } case Operator.LessThanOrEqual: { if (!isString) { result = Expression.LessThanOrEqual(leftSile, rightSide); break; } else { expressionArray = new Expression[] { rightSide }; result = Expression.LessThanOrEqual( Expression.Call(leftSile, stringCompareMethodInfo, expressionArray), Expression.Constant(0)); break; } } default: { throw new ArgumentException("Argument is not valid beacuse of operation type", "conditionForConvert"); } } return(result); }