Abilash
Abilash

Reputation: 113

How to write dynamic where in LINQ

I have a LinQ query as below

var filtered=from c in country
         where c.Id>=5
         select c;

Now i need to have the operator '>=' to be dynamic i.e., the operator may be '>=' or '==' or '<=' etc depending on a certain criteria and the query should execute based on that operator. How to achieve this in LinQ?

Upvotes: 1

Views: 164

Answers (3)

Enigmativity
Enigmativity

Reputation: 117174

I would avoid the "if-then-else" or "switch" methods, and use a "dictionary" instead.

I assume you have a control that allows the user to select the number (ie 5) too, so you would need a way to "dynamically" add this to the query too.

Define this dictionary:

var filters = new Dictionary<string,
    Func<IQueryable<Country>, int, IQueryable<Country>>>()
{
    { ">", (cs, n) => cs.Where(c => c.Id > n) },
    { ">=", (cs, n) => cs.Where(c => c.Id >= n) },
    { "==", (cs, n) => cs.Where(c => c.Id == n) },
    { "<=", (cs, n) => cs.Where(c => c.Id <= n) },
    { "<", (cs, n) => cs.Where(c => c.Id < n) },
};

Now you can populate your drop-down with the keys from the dictionary and then you can easily get your query out by doing this:

country = filters[">"](country, 5);

Or maybe something like this:

country = filters[dd.Value](country, int.Parse(tb.Text));

Yell out if you'd like any further explanation.

Upvotes: 2

Bastardo
Bastardo

Reputation: 4152

This is not exactly what you want, however I think doing what you say is not safe and it is bad for readibility and not reusable.For those purposes I always try to use new methods and be void on them.

 public void static FilterById(int limit, string condition, IEnumerable filter, Type country)
 {  
    var countryQueryable = country.AsQueryable();//Edit inspired by devio's comment on  Mr.Hilgarth's answer. 

    switch(condition)
   {
      case(">") :
      {
        filter = countryQueryable .Where(q=>q.Id > 5)
        break;
       } 
       case(">=") :
       {
         filter = countryQueryable .Where(q=>q.Id >= 5)
         break;
        } 
        case("=") :
        {
          filter = countryQueryable .Where(q=>q.Id == 5)
          break;
         } 
        case("<=") :
        {
          filter = countryQueryable .Where(q=>q.Id <= 5)
          break;
         } 
         case("<") :
         {
          filter = countryQueryable .Where(q=>q.Id < 5)
          break;
         } 
     }
}

EDIT: Dynamic LINQ (Part 1: Using the LINQ Dynamic Query Library) might help a bit.

Upvotes: 0

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174457

You can do it like this:

var filtered = country.AsQueryable();
if(cond == 0)
    filtered = filtered.Where(c => c.Id <= 5);
else if(cond == 1)
    filtered = filtered.Where(c => c.Id >= 5);
else if(cond == 2)
    filtered = filtered.Where(c => c.Id == 5);

Upvotes: 3

Related Questions