public class FilterExpressionHelper<T> where T : class
{
public FilterExpressionHelper()
{
CriteriaCollection = new List<BinaryExpression>();
}
public List<BinaryExpression> CriteriaCollection { get; set; }
public Expression<Func<T, bool>> NoFilterExpression { get; set; }
public void RemoveFilterCriteriaFilterDescriptor(Telerik.Windows.Data.FilterDescriptor d)
{
string member = d.Member;
object value = d.Value;
System.Linq.Expressions.Expression expression = System.Linq.Expressions.Expression.Parameter(typeof(T), "e");
foreach (var property in member.Split('.'))
{
expression = System.Linq.Expressions.Expression.PropertyOrField(expression, property);
}
ConstantExpression c = System.Linq.Expressions.Expression.Constant(value, typeof(string));
BinaryExpression b = System.Linq.Expressions.Expression.Equal(expression, c);
BinaryExpression expr = CriteriaCollection.Where(cr => cr.Right.ToString() == b.Right.ToString()).FirstOrDefault();
CriteriaCollection.Remove(expr);
}
public void AddFilterCriteriaFilterDescriptor(Telerik.Windows.Data.FilterDescriptor d)
{
string member = d.Member;
object value = d.Value;
System.Linq.Expressions.Expression expression = System.Linq.Expressions.Expression.Parameter(typeof(T), "e");
foreach (var property in member.Split('.'))
{
expression = System.Linq.Expressions.Expression.PropertyOrField(expression, property);
}
ConstantExpression c = System.Linq.Expressions.Expression.Constant(value, value.GetType());
BinaryExpression b = null;
switch (d.Operator)
{
case FilterOperator.IsEqualTo:
b = System.Linq.Expressions.Expression.Equal(expression, c);
break;
case FilterOperator.Contains:
//b = GetExpression<T>(expression.ToString(), value.ToString()).Body as BinaryExpression;
break;
case FilterOperator.IsGreaterThanOrEqualTo:
b = System.Linq.Expressions.Expression.GreaterThanOrEqual(expression, c);
break;
case FilterOperator.IsLessThanOrEqualTo:
b = System.Linq.Expressions.Expression.LessThanOrEqual(expression, c);
break;
}
CriteriaCollection.Add(b);
}
public Expression<Func<T, bool>> GetLambdaExpression()
{
ParameterExpression e = System.Linq.Expressions.Expression.Parameter(typeof(T), "e");
var orderedList = CriteriaCollection.OrderBy(cr => cr.Left.ToString()).ToList();
var disctinctValues = CriteriaCollection.Distinct(new BinaryExpressionComparer()).ToList();
List<BinaryExpression> orElseExpressionList = new List<BinaryExpression>();
foreach (var value in disctinctValues)
{
System.Linq.Expressions.BinaryExpression expression = null;
foreach (var criteria in orderedList.Where(cr => cr.Left.ToString().Equals(value.Left.ToString())))
{
if (expression == null)
{
expression = criteria;
}
else
{
if (expression.Left.ToString() == criteria.Left.ToString())
expression = System.Linq.Expressions.BinaryExpression.OrElse(expression, criteria);
else
expression = System.Linq.Expressions.BinaryExpression.AndAlso(expression, criteria);
}
}
orElseExpressionList.Add(expression);
}
System.Linq.Expressions.BinaryExpression expressionAnd = null;
foreach (var ex in orElseExpressionList)
{
if (expressionAnd == null)
{
expressionAnd = ex;
}
else
{
expressionAnd = System.Linq.Expressions.BinaryExpression.AndAlso(expressionAnd, ex);
}
}
if (expressionAnd != null)
{
return System.Linq.Expressions.Expression.Lambda<Func<T, bool>>(expressionAnd, e);
}
else
{
return NoFilterExpression;
}
}
static Expression<Func<T, bool>> GetExpression<T>(string propertyName, string propertyValue)
{
var parameterExp = Expression.Parameter(typeof(T), "type");
var propertyExp = Expression.Property(parameterExp, propertyName);
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var someValue = Expression.Constant(propertyValue, typeof(string));
var containsMethodExp = Expression.Call(propertyExp, method, someValue);
return BinaryExpression.Lambda<Func<T, bool>>(containsMethodExp, parameterExp);
}
private static System.Linq.Expressions.BinaryExpression Like(Expression lhs, Expression rhs)
{
//typeof(string).GetMethod("Contains", new Type[] { typeof(string) }, null);
Expression expression = Expression.Call(
typeof(FileInfoHelper).GetMethod("Like",
BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)
, lhs, rhs);
return expression as BinaryExpression;
}
class BinaryExpressionComparer : IEqualityComparer<BinaryExpression>
{
#region IEqualityComparer<Contact> Members
public bool Equals(BinaryExpression x, BinaryExpression y)
{
return x.Left.ToString().Equals(y.Left.ToString());
}
public int GetHashCode(BinaryExpression obj)
{
return obj.Left.ToString().GetHashCode();
}
#endregion
}
}