A while back, I was coming up with a LINQ query that could see if value in the database was between a set of ranges.
Take for example, I have a Person record in a database, and there’s an Age field for the person.
Now I have a page that allows me to filter for people in certain age ranges.
For example, I can choose multiple range selections, such as “0-10″, “11-20″, “31-40″.
So in this case, I’d get back a list of people between 0 and 20, as well as 30 to 40, but not 21-30.
I’ve taken the age ranges and populated a List of ranges that looks like this:
class NumberRange
{
decimal Min { get; set; }
decimal Max { get; set; }
}
List<NumberRange> ageRanges = GetAgeRanges();
With a little bit of help from the small PredicateBuilder class, I was able to write an extension method for IQueryable.
static IQueryable<T> InRange<T>(this IQueryable<T> query, Expression<Func<T, decimal>> predicate, IEnumerable<NumberRange> ranges)
{
var exp = PredicateBuilder.False<T>();
foreach (var range in ranges)
{
exp = exp.Or(
Expression.Lambda<Func<T, bool>>(Expression.GreaterThanOrEqual(predicate.Body, Expression.Constant(range.Min)), predicate.Parameters))
.And(Expression.Lambda<Func<T, bool>>(Expression.LessThanOrEqual(predicate.Body, Expression.Constant(range.Max)), predicate.Parameters));
}
return query.Where(exp);
}
So now let’s say I have a collection of Persons (People) and I want to get people within only a specific range.
I could do the following
people.InRange(person => person.Age, ageRanges);
And get just the people in the range I want.
At work, we’re actually doing this for a range of prices, which is why I’m using the decimal type in this example. If you were doing ages, the Integer or Short type would be more appropriate.


