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 '开发者_如何学Python>=' or '==' or '<=' etc depending on a certain criteria and the query should execute based on that operator. How to achieve this in LinQ?
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);
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.
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.
精彩评论