private static bool TestValue(T obj, string _findProp, object _findValue, Tenor.Data.CompareOperator _findOperator) { object valor = Util.GetValue(_findProp, obj); bool returnValue = false; switch (_findOperator) { case Tenor.Data.CompareOperator.Equal: case Tenor.Data.CompareOperator.NotEqual: if (valor == null && _findValue == null) { returnValue = true; } else if (valor == null || _findValue == null) { returnValue = false; } else { if (valor.GetType().IsValueType) { returnValue = object.Equals(valor, _findValue); } else if (valor.GetType() == typeof(string)) { returnValue = string.Equals(valor, _findValue); } else { returnValue = valor == _findValue; } } if (_findOperator == Tenor.Data.CompareOperator.NotEqual) { returnValue = !returnValue; } break; default: throw (new ArgumentException()); } return(returnValue); }
private void ReadWhereExpressions(Tenor.Data.ConditionCollection cc, Expression ex, bool not, string alias) { switch (ex.NodeType) { case ExpressionType.Quote: { UnaryExpression une = ex as UnaryExpression; if (une.IsLifted || une.IsLiftedToNull) { throw new NotImplementedException(); } ReadWhereExpressions(cc, une.Operand, not, alias); } break; case ExpressionType.Lambda: { LambdaExpression lex = ex as LambdaExpression; //TODO: Should we check parameters? ReadWhereExpressions(cc, lex.Body, not, alias); } break; case ExpressionType.Not: { UnaryExpression une = ex as UnaryExpression; if (une.IsLifted || une.IsLiftedToNull) { throw new NotImplementedException(); } ReadWhereExpressions(cc, une.Operand, !not, alias); } break; case ExpressionType.And: case ExpressionType.AndAlso: { BinaryExpression andBinary = ex as BinaryExpression; Tenor.Data.ConditionCollection newCc = new Tenor.Data.ConditionCollection(); ReadWhereExpressions(newCc, andBinary.Left, not, alias); newCc.Add(Tenor.Data.LogicalOperator.And); ReadWhereExpressions(newCc, andBinary.Right, not, alias); if (cc.Count > 0 && cc[cc.Count - 1].GetType() != typeof(Tenor.Data.LogicalOperator)) { cc.Add(Tenor.Data.LogicalOperator.And); } cc.Add(newCc); } break; case ExpressionType.Or: case ExpressionType.OrElse: { BinaryExpression andBinary = ex as BinaryExpression; Tenor.Data.ConditionCollection newCc = new Tenor.Data.ConditionCollection(); ReadWhereExpressions(newCc, andBinary.Left, not, alias); newCc.Add(Tenor.Data.LogicalOperator.Or); ReadWhereExpressions(newCc, andBinary.Right, not, alias); if (cc.Count > 0 && cc[cc.Count - 1].GetType() != typeof(Tenor.Data.LogicalOperator)) { cc.Add(Tenor.Data.LogicalOperator.And); } cc.Add(newCc); } break; case ExpressionType.Equal: case ExpressionType.NotEqual: case ExpressionType.LessThan: case ExpressionType.LessThanOrEqual: case ExpressionType.GreaterThan: case ExpressionType.GreaterThanOrEqual: { BinaryExpression bex = ex as BinaryExpression; bool lower = false, upper = false; if (bex.Left.NodeType == ExpressionType.Call) { var call = (bex.Left as MethodCallExpression); lower = (call.Method.Name == "ToLower"); upper = (call.Method.Name == "ToUpper"); } MemberExpression left = ReadOperand(bex, false) as MemberExpression; bool invertOperator = false; Expression right = ReadOperand(bex, true, ref invertOperator); if (ex.NodeType != ExpressionType.Equal && ex.NodeType != ExpressionType.NotEqual && invertOperator) { not = !not; } //check if we need another alias if (left.Expression != null && left.Expression is MemberExpression) { MemberExpression lExp = (MemberExpression)left.Expression; if (lExp.Member.MemberType == MemberTypes.Property) { alias = IncludeAlias(cc, lExp, alias); } } Tenor.Data.CompareOperator op = Tenor.Data.CompareOperator.Equal; if (ex.NodeType == ExpressionType.Equal && !not) { op = Tenor.Data.CompareOperator.Equal; } else if (ex.NodeType == ExpressionType.Equal && not) { op = Tenor.Data.CompareOperator.NotEqual; } else if (ex.NodeType == ExpressionType.NotEqual && !not) { op = Tenor.Data.CompareOperator.NotEqual; } else if (ex.NodeType == ExpressionType.NotEqual && not) { op = Tenor.Data.CompareOperator.Equal; } else if (ex.NodeType == ExpressionType.GreaterThan && !not) { op = Tenor.Data.CompareOperator.GreaterThan; } else if (ex.NodeType == ExpressionType.GreaterThan && not) { op = Tenor.Data.CompareOperator.LessThan; } else if (ex.NodeType == ExpressionType.LessThan && !not) { op = Tenor.Data.CompareOperator.LessThan; } else if (ex.NodeType == ExpressionType.LessThan && not) { op = Tenor.Data.CompareOperator.GreaterThan; } else if (ex.NodeType == ExpressionType.GreaterThanOrEqual && !not) { op = Tenor.Data.CompareOperator.GreaterThanOrEqual; } else if (ex.NodeType == ExpressionType.GreaterThanOrEqual && not) { op = Tenor.Data.CompareOperator.LessThanOrEqual; } else if (ex.NodeType == ExpressionType.LessThanOrEqual && !not) { op = Tenor.Data.CompareOperator.LessThanOrEqual; } else if (ex.NodeType == ExpressionType.LessThanOrEqual && not) { op = Tenor.Data.CompareOperator.GreaterThanOrEqual; } if (op == Data.CompareOperator.Equal) { if (upper) { op = Tenor.Data.CompareOperator.EqualUpper; } else if (lower) { op = Tenor.Data.CompareOperator.EqualLower; } } else if (op == Data.CompareOperator.NotEqual) { if (upper) { op = Tenor.Data.CompareOperator.NotEqualUpper; } else if (lower) { op = Tenor.Data.CompareOperator.NotEqualLower; } } if (cc.Count > 0 && !(cc[cc.Count - 1] is Tenor.Data.LogicalOperator)) { cc.Add(Data.LogicalOperator.And); } cc.Add(left.Member.Name, FindValue(right), op, alias); } break; case ExpressionType.MemberAccess: { MemberExpression mex = ex as MemberExpression; if (mex.Type != typeof(bool) && (!mex.Type.IsGenericType || mex.Type != typeof(bool?))) { throw new InvalidOperationException("Invalid lambda expression"); } Tenor.Data.CompareOperator op = Tenor.Data.CompareOperator.Equal; if (not) { op = Tenor.Data.CompareOperator.NotEqual; } if (cc.Count > 0 && cc[cc.Count - 1].GetType() != typeof(Tenor.Data.LogicalOperator)) { cc.Add(Tenor.Data.LogicalOperator.And); } cc.Add(mex.Member.Name, true, op, alias); } break; case ExpressionType.Call: { MethodCallExpression mce = (MethodCallExpression)ex; switch (mce.Method.Name) { case "Contains": case "StartsWith": case "EndsWith": { MemberExpression member = (mce.Object != null ? mce.Object : mce.Arguments[0]) as MemberExpression; MemberExpression property = (mce.Object != null ? mce.Arguments[0] : mce.Arguments[1]) as MemberExpression; MethodCallExpression methodCall = (mce.Object != null ? mce.Arguments[0] : mce.Arguments[1]) as MethodCallExpression; if (mce.Method.Name == "Contains" && member.Type != typeof(string)) { // In Tenor.Data.ConditionCollection inValues = new Data.ConditionCollection(); IList list = FindValue(member) as IList; foreach (object v in list) { if (inValues.Count > 0) { inValues.Add(Data.LogicalOperator.Or); } inValues.Add(property.Member.Name, v, Data.CompareOperator.Equal, alias); } if (inValues.Count > 0) { cc.Add(inValues); } } else if (member.Type == typeof(string)) { //this will generate a like expression string str = property != null? FindValue(property) as string : FindValue(methodCall) as string; if (mce.Method.Name == "StartsWith") { str = string.Format("{0}%", str); } else if (mce.Method.Name == "EndsWith") { str = string.Format("%{0}", str); } else if (mce.Method.Name == "Contains") { str = string.Format("%{0}%", str); } Tenor.Data.CompareOperator op = Tenor.Data.CompareOperator.Like; if (not) { op = Tenor.Data.CompareOperator.NotLike; } cc.Add(member.Member.Name, str, op, alias); } else { throw new NotImplementedException(string.Format("{0} not implemented with current parameters.", mce.Method.Name)); } } break; case "Any": { //here we will join. MemberExpression member = mce.Arguments[0] as MemberExpression; string newAlias = GenerateAliasForMember(alias, member); Tenor.Data.ConditionCollection newCc = new Tenor.Data.ConditionCollection(); ReadWhereExpressions(newCc, mce.Arguments[1], not, newAlias); if (cc.Count > 0 && cc[cc.Count - 1].GetType() != typeof(Tenor.Data.LogicalOperator)) { cc.Add(Tenor.Data.LogicalOperator.And); } cc.Add(newCc); } break; default: throw new NotImplementedException("Linq method call to '" + mce.Method.Name + "' is not implemented. Please, send a feature request."); } } break; default: throw new NotImplementedException("Linq '" + ex.NodeType.ToString() + "' is not implemented. Please, send a feature request."); } }
/// <summary> /// Searchs for entities on this collection. /// </summary> /// <param name="propertyExpression">The property name used to match entities. You can use dot (.) separated properties to go down on the class.</param> /// <param name="value">The value desired.</param> /// <param name="compareOperator">The compare operator to use against the property.</param> /// <returns>The index of the last found entity.</returns> public int FindLastIndex(string propertyExpression, object value, Tenor.Data.CompareOperator compareOperator) { SetFindDefinitions(propertyExpression, value, compareOperator); return(list.FindLastIndex(new Predicate <T>(FindDelegate))); }
/// <summary> /// Searchs for entities on this collection. /// </summary> /// <param name="propertyExpression">The property name used to match entities. You can use dot (.) separated properties to go down on the class.</param> /// <param name="value">A value to be compared.</param> /// <param name="compareOperator">The compare operator to use against the property.</param> /// <returns>An array of entities found.</returns> public T[] FindAll(string propertyExpression, object value, Tenor.Data.CompareOperator compareOperator) { SetFindDefinitions(propertyExpression, value, compareOperator); return(list.FindAll(new Predicate <T>(FindDelegate)).ToArray()); }
private void SetFindDefinitions(string PropertyExpression, object Value, Tenor.Data.CompareOperator @Operator) { SetFindDefinitions(new string[] { PropertyExpression }, new object[] { Value }, new Tenor.Data.CompareOperator[] { @Operator }, new Tenor.Data.LogicalOperator[] { }); }
/// <summary> /// Search for an object on the collection. /// </summary> /// <param name="items">An array of entities.</param> /// <param name="propertyExpression">The property name used to match entities. You can use dot (.) separated properties to go down on the class.</param> /// <param name="value">The value desired.</param> /// <param name="compareOperator">The compare operator to use against the property.</param> /// <returns>The last found object.</returns> public static EntityBase FindLast(EntityBase[] items, string propertyExpression, object value, Tenor.Data.CompareOperator compareOperator) { return(FindLast <EntityBase>(items, propertyExpression, value, compareOperator)); }
/// <summary> /// Search for an object on the collection. /// </summary> /// <param name="items">An array of entities.</param> /// <param name="propertyExpression">The property name used to match entities. You can use dot (.) separated properties to go down on the class.</param> /// <param name="value">The value desired.</param> /// <param name="compareOperator">The compare operator to use against the property.</param> /// <returns>The last found object.</returns> public static T FindLast <T>(T[] items, string propertyExpression, object value, Tenor.Data.CompareOperator compareOperator) where T : EntityBase { SetFindDefinitions <T>(propertyExpression, value, compareOperator); return(Array.FindLast <T>(items, new Predicate <T>(EntityList <T> .FindDelegate))); }
private static void SetFindDefinitions <t>(string PropertyExpression, object Value, Tenor.Data.CompareOperator @Operator) where t : EntityBase { //TODO: Consider coding an anonymous delegate. SetFindDefinitions <t>(new string[] { PropertyExpression }, new object[] { Value }, new Tenor.Data.CompareOperator[] { @Operator }, new Tenor.Data.LogicalOperator[0]); }