1

Given the following string arrray:

string[] ranges = new string[]{"0-100", "100-200", "500-1000"};

I would like to dynamically express this in a linq expression - Something along the lines of:

var query = from p in Db.Products()
            where p.Amount() >= 0
            where p.Amount() <= 100
            where p.Amount() >= 101
            where p.Amount() <= 200
            where p.Amount() >= 500
            where p.Amount() <= 1000
            select p;

I know how to extract the values from the array so that's not the issue, but more so how do i dynamically build the linq expression in a for loop:

string[] ranges = new string[]{"0-100", "100-200", "500-1000"};

foreach (var item in ranges)
{
    int min = int.Parse(item.Split('-').First());
    int max = int.Parse(item.Split('-').Last());                
    //Linq expression?
}
Fixer
  • 5,985
  • 8
  • 40
  • 58
  • 1
    Note; be very very careful not to use `item` itself **directly** in any expression tree; that will capture the **variable**, not the value at any given iteration. The current approach obtaining `min` and `max` etc, and using **those** in the query is fine though. – Marc Gravell Mar 15 '12 at 11:42

2 Answers2

5

Like this:

IQueryable<Product> query = DB.Products();
foreach (var item in ranges)
{
    int min = int.Parse(item.Split('-').First());
    int max = int.Parse(item.Split('-').Last());                
    query = query.Where(p => p.Amount() >= min && p.Amount() <= max);
}

(I've only got half the where clauses you had, but it's equivalent. You can break it up if you really want.)

Note the assignment back to query - methods like Where return a new query which is the result of applying the operation to the existing query; they don't change anything in the existing query.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Can IEnumerable be used over IQueryable? – Fixer Mar 15 '12 at 11:49
  • @Fixer: It depends where you want the query to be performed. Given the name, I assumed this was a LINQ to SQL query or something similar. If it's LINQ to Objects - or if you *want* the filtering to be done locally - then yes, you can absolutely use `IEnumerable`. – Jon Skeet Mar 15 '12 at 11:55
1

Try out with following code:

           var result= from range in ranges
                       select new 
                       {
                           min = int.Parse(range.Split('-').First()),
                           max = int.Parse(range.Split('-').Last()) 
                       };

result contains all min and max....