Reputation: 13
I have as scenario like this:
One supposed query
var list = (from p in context.table select p.field)
and different "orderby" based on the client choice .
The simple way to do it would look like this:
if (filter.Equals("filter1"))
{
var list = (from p in context.table select p.field).OrderBy(w=> w.filter1);
}
else if (filter.Equals("filter2"))
{
var list = (from p in context.table select p.field).OrderBy(w=> w.filter2);
}
But since there is a lot of filters, it feels like it is an ugly practice to repeat the same query a lot of times just to change the OrderBy
condition, does someone know what would be the best/cleaner approach?
Upvotes: 0
Views: 68
Reputation: 27282
I would suggest another approach with extension method.
var q = (from p in context.table select p)
.OrderByIf(filter.Equals("filter1"), w => w.filter1)
.OrderByIf(filter.Equals("filter2"), w => w.filter2)
.OrderByIf(filter.Equals("filter2"), w => w.filter2)
...
;
var list = q.Select(x => x.field).ToList();
public static class QueryableExtensions
{
public static IQueryable<T> OrderByIf<T, TKey>(this IQueryable<T> query,
bool cond, Expression<Func<T, TKey>> prop)
{
if (cond)
{
query = query.OrderBy(prop);
}
return query;
}
}
Upvotes: 0
Reputation: 6605
first of all, I think, what you did is not bad at all. pretty straightforward. but if you really want to make it 'better' (actually not sure it is better, but at least it is a way):
var q = (from p in context.table select p)
.OrderBy(w => filter.Equals("filter1") ? w.filter1 : "")
.OrderBy(w => filter.Equals("filter2") ? w.filter2 : "")
.OrderBy(w => filter.Equals("filter3") ? w.filter3 : "")
...
;
var list = q.Select(x => x.field).ToList();
something like this
Upvotes: 0
Reputation: 26907
If your filters vary in type, you can use a switch
-case
to select a filter:
var query = from p in context.table select p;
switch (filter) {
case "filter1":
query = query.OrderBy(r => r.filter1);
break;
case "filter2":
query = query.OrderBy(r => r.filter2);
break;
}
var list = query.Select(r => r.field).ToList();
If your filters are uniform in type, you can use a Dictionary
to lookup the filter lambda Expression
:
var q2 = from p in context.table select p;
var filterMap = new Dictionary<string, Expression<Func<Table, int>>> {
{ "filter1", (Table r) => r.filter1 },
{ "filter2", (Table r) => r.filter2 },
};
if (filterMap.TryGetValue(filter, out var orderFne))
q2 = q2.OrderBy(orderFne);
var l2 = query.Select(r => r.field).ToList();
Upvotes: 2