public static FilterContainer GenerateFilterDescription <T>(this Expression expression) where T : class { var expType = expression.NodeType; if (expType == ExpressionType.AndAlso) { var binaryExpression = expression as BinaryExpression; var leftFilter = GenerateFilterDescription <T>(binaryExpression.Left); var rightFilter = GenerateFilterDescription <T>(binaryExpression.Right); var filterDescriptor = new FilterDescriptor <T>(); return(filterDescriptor.And(leftFilter, rightFilter)); } else if (expType == ExpressionType.Or || expType == ExpressionType.OrElse) { var binaryExpression = expression as BinaryExpression; var leftFilter = GenerateFilterDescription <T>(binaryExpression.Left); var rightFilter = GenerateFilterDescription <T>(binaryExpression.Right); var filterDescriptor = new FilterDescriptor <T>(); return(filterDescriptor.Or(leftFilter, rightFilter)); } else if (expType == ExpressionType.Equal) { return(GenerateEqualityFilter <T>(expression)); } else if (expType == ExpressionType.LessThan || expType == ExpressionType.GreaterThan || expType == ExpressionType.LessThanOrEqual || expType == ExpressionType.GreaterThanOrEqual) { return(GenerateComparisonFilter <T>(expression, expType)); } else if (expType == ExpressionType.MemberAccess) { var memberExpression = expression as MemberExpression; //here we handle binary expressions in the from .field.hasValue if (memberExpression.Member.Name == "HasValue") { var parentFieldExpression = (memberExpression.Expression as MemberExpression); var parentFieldName = GetFieldNameFromMember(parentFieldExpression); var filterDescriptor = new FilterDescriptor <T>(); return(filterDescriptor.Exists(parentFieldName)); } var isProperty = memberExpression.Member.MemberType == MemberTypes.Property; if (isProperty) { var propertyType = ((PropertyInfo)memberExpression.Member).PropertyType; if (propertyType == typeof(bool)) { return(GenerateBoolFilter <T>(memberExpression)); } } } else if (expType == ExpressionType.Lambda) { var lambda = expression as LambdaExpression; return(GenerateFilterDescription <T>(lambda.Body)); } else if (expType == ExpressionType.NotEqual) { return(GenerateNotEqualFilter <T>(expression)); } throw new NotImplementedException(); }